diff options
Diffstat (limited to 'host/examples')
30 files changed, 3517 insertions, 3081 deletions
diff --git a/host/examples/ascii_art_dft.hpp b/host/examples/ascii_art_dft.hpp index bb038a155..19099cbf8 100644 --- a/host/examples/ascii_art_dft.hpp +++ b/host/examples/ascii_art_dft.hpp @@ -8,281 +8,315 @@ #ifndef ASCII_ART_DFT_HPP #define ASCII_ART_DFT_HPP -#include <string> -#include <cstddef> -#include <vector> #include <complex> +#include <cstddef> #include <stdexcept> +#include <string> +#include <vector> -namespace ascii_art_dft{ - - //! Type produced by the log power DFT function - typedef std::vector<float> log_pwr_dft_type; - - /*! - * Get a logarithmic power DFT of the input samples. - * Samples are expected to be in the range [-1.0, 1.0]. - * \param samps a pointer to an array of complex samples - * \param nsamps the number of samples in the array - * \return a real range of DFT bins in units of dB - */ - template <typename T> log_pwr_dft_type log_pwr_dft( - const std::complex<T> *samps, size_t nsamps - ); - - /*! - * Convert a DFT to a piroundable ascii plot. - * \param dft the log power dft bins - * \param width the frame width in characters - * \param height the frame height in characters - * \param samp_rate the sample rate in Sps - * \param dc_freq the DC frequency in Hz - * \param dyn_rng the dynamic range in dB - * \param ref_lvl the reference level in dB - * \return the plot as an ascii string - */ - std::string dft_to_plot( - const log_pwr_dft_type &dft, - size_t width, - size_t height, - double samp_rate, - double dc_freq, - float dyn_rng, - float ref_lvl - ); - -} //namespace ascii_dft +namespace ascii_art_dft { + +//! Type produced by the log power DFT function +typedef std::vector<float> log_pwr_dft_type; + +/*! + * Get a logarithmic power DFT of the input samples. + * Samples are expected to be in the range [-1.0, 1.0]. + * \param samps a pointer to an array of complex samples + * \param nsamps the number of samples in the array + * \return a real range of DFT bins in units of dB + */ +template <typename T> +log_pwr_dft_type log_pwr_dft(const std::complex<T>* samps, size_t nsamps); + +/*! + * Convert a DFT to a piroundable ascii plot. + * \param dft the log power dft bins + * \param width the frame width in characters + * \param height the frame height in characters + * \param samp_rate the sample rate in Sps + * \param dc_freq the DC frequency in Hz + * \param dyn_rng the dynamic range in dB + * \param ref_lvl the reference level in dB + * \return the plot as an ascii string + */ +std::string dft_to_plot(const log_pwr_dft_type& dft, + size_t width, + size_t height, + double samp_rate, + double dc_freq, + float dyn_rng, + float ref_lvl); + +} // namespace ascii_art_dft /*********************************************************************** * Implementation includes **********************************************************************/ +#include <algorithm> #include <cmath> #include <sstream> -#include <algorithm> /*********************************************************************** * Helper functions **********************************************************************/ -namespace {/*anon*/ +namespace { /*anon*/ + +static const double pi = double(std::acos(-1.0)); - static const double pi = double(std::acos(-1.0)); +//! Round a floating-point value to the nearest integer +template <typename T> int iround(T val) +{ + return (val > 0) ? int(val + 0.5) : int(val - 0.5); +} - //! Round a floating-point value to the nearest integer - template <typename T> int iround(T val){ - return (val > 0)? int(val + 0.5) : int(val - 0.5); +//! Pick the closest number that is nice to display +template <typename T> T to_clean_num(const T num) +{ + if (num == 0) + return 0; + const T pow10 = std::pow(T(10), int(std::floor(std::log10(std::abs(num))))); + const T norm = std::abs(num) / pow10; + static const int cleans[] = {1, 2, 5, 10}; + int clean = cleans[0]; + for (size_t i = 1; i < sizeof(cleans) / sizeof(cleans[0]); i++) { + if (std::abs(norm - cleans[i]) < std::abs(norm - clean)) + clean = cleans[i]; } + return ((num < 0) ? -1 : 1) * clean * pow10; +} - //! Pick the closest number that is nice to display - template <typename T> T to_clean_num(const T num){ - if (num == 0) return 0; - const T pow10 = std::pow(T(10), int(std::floor(std::log10(std::abs(num))))); - const T norm = std::abs(num)/pow10; - static const int cleans[] = {1, 2, 5, 10}; - int clean = cleans[0]; - for (size_t i = 1; i < sizeof(cleans)/sizeof(cleans[0]); i++){ - if (std::abs(norm - cleans[i]) < std::abs(norm - clean)) - clean = cleans[i]; - } - return ((num < 0)? -1 : 1)*clean*pow10; +//! Compute an FFT with pre-computed factors using Cooley-Tukey +template <typename T> +std::complex<T> ct_fft_f(const std::complex<T>* samps, + size_t nsamps, + const std::complex<T>* factors, + size_t start = 0, + size_t step = 1) +{ + if (nsamps == 1) + return samps[start]; + std::complex<T> E_k = ct_fft_f(samps, nsamps / 2, factors + 1, start, step * 2); + std::complex<T> O_k = + ct_fft_f(samps, nsamps / 2, factors + 1, start + step, step * 2); + return E_k + factors[0] * O_k; +} + +//! Compute an FFT for a particular bin k using Cooley-Tukey +template <typename T> +std::complex<T> ct_fft_k(const std::complex<T>* samps, size_t nsamps, size_t k) +{ + // pre-compute the factors to use in Cooley-Tukey + std::vector<std::complex<T>> factors; + for (size_t N = nsamps; N != 0; N /= 2) { + factors.push_back(std::exp(std::complex<T>(0, T(-2 * pi * k / N)))); } + return ct_fft_f(samps, nsamps, &factors.front()); +} - //! Compute an FFT with pre-computed factors using Cooley-Tukey - template <typename T> std::complex<T> ct_fft_f( - const std::complex<T> *samps, size_t nsamps, - const std::complex<T> *factors, - size_t start = 0, size_t step = 1 - ){ - if (nsamps == 1) return samps[start]; - std::complex<T> E_k = ct_fft_f(samps, nsamps/2, factors+1, start, step*2); - std::complex<T> O_k = ct_fft_f(samps, nsamps/2, factors+1, start+step, step*2); - return E_k + factors[0]*O_k; +//! Helper class to build a DFT plot frame +class frame_type +{ +public: + frame_type(size_t width, size_t height) + : _frame(width - 1, std::vector<char>(height, ' ')) + { + /* NOP */ } - //! Compute an FFT for a particular bin k using Cooley-Tukey - template <typename T> std::complex<T> ct_fft_k( - const std::complex<T> *samps, size_t nsamps, size_t k - ){ - //pre-compute the factors to use in Cooley-Tukey - std::vector<std::complex<T> > factors; - for (size_t N = nsamps; N != 0; N /= 2){ - factors.push_back(std::exp(std::complex<T>(0, T(-2*pi*k/N)))); - } - return ct_fft_f(samps, nsamps, &factors.front()); + // accessors to parts of the frame + char& get_plot(size_t b, size_t z) + { + return _frame.at(b + albl_w).at(z + flbl_h); + } + char& get_albl(size_t b, size_t z) + { + return _frame.at(b).at(z + flbl_h); + } + char& get_ulbl(size_t b) + { + return _frame.at(b).at(flbl_h - 1); + } + char& get_flbl(size_t b) + { + return _frame.at(b + albl_w).at(flbl_h - 1); } - //! Helper class to build a DFT plot frame - class frame_type{ - public: - frame_type(size_t width, size_t height): - _frame(width-1, std::vector<char>(height, ' ')) - { - /* NOP */ - } + // dimension accessors + size_t get_plot_h(void) const + { + return _frame.front().size() - flbl_h; + } + size_t get_plot_w(void) const + { + return _frame.size() - albl_w; + } + size_t get_albl_w(void) const + { + return albl_w; + } - //accessors to parts of the frame - char &get_plot(size_t b, size_t z){return _frame.at(b+albl_w).at(z+flbl_h);} - char &get_albl(size_t b, size_t z){return _frame.at(b) .at(z+flbl_h);} - char &get_ulbl(size_t b) {return _frame.at(b) .at(flbl_h-1);} - char &get_flbl(size_t b) {return _frame.at(b+albl_w).at(flbl_h-1);} - - //dimension accessors - size_t get_plot_h(void) const{return _frame.front().size() - flbl_h;} - size_t get_plot_w(void) const{return _frame.size() - albl_w;} - size_t get_albl_w(void) const{return albl_w;} - - std::string to_string(void){ - std::stringstream frame_ss; - for (size_t z = 0; z < _frame.front().size(); z++){ - for (size_t b = 0; b < _frame.size(); b++){ - frame_ss << _frame[b][_frame[b].size()-z-1]; - } - frame_ss << std::endl; + std::string to_string(void) + { + std::stringstream frame_ss; + for (size_t z = 0; z < _frame.front().size(); z++) { + for (size_t b = 0; b < _frame.size(); b++) { + frame_ss << _frame[b][_frame[b].size() - z - 1]; } - return frame_ss.str(); + frame_ss << std::endl; } + return frame_ss.str(); + } - private: - static const size_t albl_w = 6, flbl_h = 1; - std::vector<std::vector<char> > _frame; - }; +private: + static const size_t albl_w = 6, flbl_h = 1; + std::vector<std::vector<char>> _frame; +}; -} //namespace /*anon*/ +} // namespace /*********************************************************************** * Implementation code **********************************************************************/ -namespace ascii_art_dft{ - - //! skip constants for amplitude and frequency labels - static const size_t albl_skip = 5, flbl_skip = 20; - - template <typename T> log_pwr_dft_type log_pwr_dft( - const std::complex<T> *samps, size_t nsamps - ){ - if (nsamps & (nsamps - 1)) - throw std::runtime_error("num samps is not a power of 2"); - - //compute the window - double win_pwr = 0; - std::vector<std::complex<T> > win_samps; - for(size_t n = 0; n < nsamps; n++){ - //double w_n = 1; - //double w_n = 0.54 //hamming window - // -0.46*std::cos(2*pi*n/(nsamps-1)) - //; - double w_n = 0.35875 //blackman-harris window - -0.48829*std::cos(2*pi*n/(nsamps-1)) - +0.14128*std::cos(4*pi*n/(nsamps-1)) - -0.01168*std::cos(6*pi*n/(nsamps-1)) - ; - //double w_n = 1 // flat top window - // -1.930*std::cos(2*pi*n/(nsamps-1)) - // +1.290*std::cos(4*pi*n/(nsamps-1)) - // -0.388*std::cos(6*pi*n/(nsamps-1)) - // +0.032*std::cos(8*pi*n/(nsamps-1)) - //; - win_samps.push_back(T(w_n)*samps[n]); - win_pwr += w_n*w_n; - } - - //compute the log-power dft - log_pwr_dft_type log_pwr_dft; - for(size_t k = 0; k < nsamps; k++){ - std::complex<T> dft_k = ct_fft_k(&win_samps.front(), nsamps, k); - log_pwr_dft.push_back(float( - + 20*std::log10(std::abs(dft_k)) - - 20*std::log10(T(nsamps)) - - 10*std::log10(win_pwr/nsamps) - + 3 - )); - } +namespace ascii_art_dft { + +//! skip constants for amplitude and frequency labels +static const size_t albl_skip = 5, flbl_skip = 20; + +template <typename T> +log_pwr_dft_type log_pwr_dft(const std::complex<T>* samps, size_t nsamps) +{ + if (nsamps & (nsamps - 1)) + throw std::runtime_error("num samps is not a power of 2"); + + // compute the window + double win_pwr = 0; + std::vector<std::complex<T>> win_samps; + for (size_t n = 0; n < nsamps; n++) { + // double w_n = 1; + // double w_n = 0.54 //hamming window + // -0.46*std::cos(2*pi*n/(nsamps-1)) + //; + double w_n = 0.35875 // blackman-harris window + - 0.48829 * std::cos(2 * pi * n / (nsamps - 1)) + + 0.14128 * std::cos(4 * pi * n / (nsamps - 1)) + - 0.01168 * std::cos(6 * pi * n / (nsamps - 1)); + // double w_n = 1 // flat top window + // -1.930*std::cos(2*pi*n/(nsamps-1)) + // +1.290*std::cos(4*pi*n/(nsamps-1)) + // -0.388*std::cos(6*pi*n/(nsamps-1)) + // +0.032*std::cos(8*pi*n/(nsamps-1)) + //; + win_samps.push_back(T(w_n) * samps[n]); + win_pwr += w_n * w_n; + } - return log_pwr_dft; + // compute the log-power dft + log_pwr_dft_type log_pwr_dft; + for (size_t k = 0; k < nsamps; k++) { + std::complex<T> dft_k = ct_fft_k(&win_samps.front(), nsamps, k); + log_pwr_dft.push_back( + float(+20 * std::log10(std::abs(dft_k)) - 20 * std::log10(T(nsamps)) + - 10 * std::log10(win_pwr / nsamps) + 3)); } - std::string dft_to_plot( - const log_pwr_dft_type &dft_, - size_t width, - size_t height, - double samp_rate, - double dc_freq, - float dyn_rng, - float ref_lvl - ){ - frame_type frame(width, height); //fill this frame - - //re-order the dft so dc in in the center - const size_t num_bins = dft_.size() - 1 + dft_.size()%2; //make it odd - log_pwr_dft_type dft(num_bins); - for (size_t n = 0; n < num_bins; n++){ - dft[n] = dft_[(n + num_bins/2)%num_bins]; - } + return log_pwr_dft; +} - //fill the plot with dft bins - for (size_t b = 0; b < frame.get_plot_w(); b++){ - //indexes from the dft to grab for the plot - const size_t n_start = std::max(iround(double(b-0.5)*(num_bins-1)/(frame.get_plot_w()-1)), 0); - const size_t n_stop = std::min(iround(double(b+0.5)*(num_bins-1)/(frame.get_plot_w()-1)), int(num_bins)); - - //calculate val as the max across points - float val = dft.at(n_start); - for (size_t n = n_start; n < n_stop; n++) val = std::max(val, dft.at(n)); - - const float scaled = (val - (ref_lvl - dyn_rng))*(frame.get_plot_h()-1)/dyn_rng; - for (size_t z = 0; z < frame.get_plot_h(); z++){ - static const std::string syms(".:!|"); - if (scaled-z > 1) frame.get_plot(b, z) = syms.at(syms.size()-1); - else if (scaled-z > 0) frame.get_plot(b, z) = syms.at(size_t((scaled-z)*syms.size())); - } - } +std::string dft_to_plot(const log_pwr_dft_type& dft_, + size_t width, + size_t height, + double samp_rate, + double dc_freq, + float dyn_rng, + float ref_lvl) +{ + frame_type frame(width, height); // fill this frame + + // re-order the dft so dc in in the center + const size_t num_bins = dft_.size() - 1 + dft_.size() % 2; // make it odd + log_pwr_dft_type dft(num_bins); + for (size_t n = 0; n < num_bins; n++) { + dft[n] = dft_[(n + num_bins / 2) % num_bins]; + } - //create vertical amplitude labels - const float db_step = to_clean_num(dyn_rng/(frame.get_plot_h()-1)*albl_skip); - for ( - float db = db_step*(int((ref_lvl - dyn_rng)/db_step)); - db <= db_step*(int(ref_lvl/db_step)); - db += db_step - ){ - const int z = iround((db - (ref_lvl - dyn_rng))*(frame.get_plot_h()-1)/dyn_rng); - if (z < 0 or size_t(z) >= frame.get_plot_h()) continue; - std::stringstream ss; ss << db; std::string lbl = ss.str(); - for (size_t i = 0; i < lbl.size() and i < frame.get_albl_w(); i++){ - frame.get_albl(i, z) = lbl[i]; - } + // fill the plot with dft bins + for (size_t b = 0; b < frame.get_plot_w(); b++) { + // indexes from the dft to grab for the plot + const size_t n_start = std::max( + iround(double(b - 0.5) * (num_bins - 1) / (frame.get_plot_w() - 1)), 0); + const size_t n_stop = + std::min(iround(double(b + 0.5) * (num_bins - 1) / (frame.get_plot_w() - 1)), + int(num_bins)); + + // calculate val as the max across points + float val = dft.at(n_start); + for (size_t n = n_start; n < n_stop; n++) + val = std::max(val, dft.at(n)); + + const float scaled = + (val - (ref_lvl - dyn_rng)) * (frame.get_plot_h() - 1) / dyn_rng; + for (size_t z = 0; z < frame.get_plot_h(); z++) { + static const std::string syms(".:!|"); + if (scaled - z > 1) + frame.get_plot(b, z) = syms.at(syms.size() - 1); + else if (scaled - z > 0) + frame.get_plot(b, z) = syms.at(size_t((scaled - z) * syms.size())); } + } - //create vertical units label - std::string ulbl = "dBfs"; - for (size_t i = 0; i < ulbl.size(); i++){ - frame.get_ulbl(i+1) = ulbl[i]; + // create vertical amplitude labels + const float db_step = to_clean_num(dyn_rng / (frame.get_plot_h() - 1) * albl_skip); + for (float db = db_step * (int((ref_lvl - dyn_rng) / db_step)); + db <= db_step * (int(ref_lvl / db_step)); + db += db_step) { + const int z = + iround((db - (ref_lvl - dyn_rng)) * (frame.get_plot_h() - 1) / dyn_rng); + if (z < 0 or size_t(z) >= frame.get_plot_h()) + continue; + std::stringstream ss; + ss << db; + std::string lbl = ss.str(); + for (size_t i = 0; i < lbl.size() and i < frame.get_albl_w(); i++) { + frame.get_albl(i, z) = lbl[i]; } + } - //create horizontal frequency labels - const double f_step = to_clean_num(samp_rate/frame.get_plot_w()*flbl_skip); - for ( - double freq = f_step*int((-samp_rate/2/f_step)); - freq <= f_step*int((+samp_rate/2/f_step)); - freq += f_step - ){ - const int b = iround((freq + samp_rate/2)*(frame.get_plot_w()-1)/samp_rate); - std::stringstream ss; ss << (freq+dc_freq)/1e6 << "MHz"; std::string lbl = ss.str(); - if (b < int(lbl.size()/2) or b + lbl.size() - lbl.size()/2 >= frame.get_plot_w()) continue; - for (size_t i = 0; i < lbl.size(); i++){ - frame.get_flbl(b + i - lbl.size()/2) = lbl[i]; - } - } + // create vertical units label + std::string ulbl = "dBfs"; + for (size_t i = 0; i < ulbl.size(); i++) { + frame.get_ulbl(i + 1) = ulbl[i]; + } - return frame.to_string(); + // create horizontal frequency labels + const double f_step = to_clean_num(samp_rate / frame.get_plot_w() * flbl_skip); + for (double freq = f_step * int((-samp_rate / 2 / f_step)); + freq <= f_step * int((+samp_rate / 2 / f_step)); + freq += f_step) { + const int b = + iround((freq + samp_rate / 2) * (frame.get_plot_w() - 1) / samp_rate); + std::stringstream ss; + ss << (freq + dc_freq) / 1e6 << "MHz"; + std::string lbl = ss.str(); + if (b < int(lbl.size() / 2) + or b + lbl.size() - lbl.size() / 2 >= frame.get_plot_w()) + continue; + for (size_t i = 0; i < lbl.size(); i++) { + frame.get_flbl(b + i - lbl.size() / 2) = lbl[i]; + } } -} //namespace ascii_dft + + return frame.to_string(); +} +} // namespace ascii_art_dft /* //example main function to test the dft -#include <iostream> -#include <cstdlib> #include <curses.h> +#include <cstdlib> +#include <iostream> int main(void){ initscr(); diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp index 5e997f59a..b97de09ac 100644 --- a/host/examples/benchmark_rate.cpp +++ b/host/examples/benchmark_rate.cpp @@ -5,49 +5,50 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> #include <uhd/convert.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> -#include <boost/thread/thread.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/algorithm/string.hpp> #include <boost/date_time/posix_time/posix_time.hpp> -#include <iostream> -#include <complex> -#include <cstdlib> +#include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <boost/thread/thread.hpp> #include <atomic> #include <chrono> +#include <complex> +#include <cstdlib> +#include <iostream> #include <thread> namespace po = boost::program_options; namespace { - constexpr int64_t CLOCK_TIMEOUT = 1000; // 1000mS timeout for external clock locking - constexpr float INIT_DELAY = 0.05; // 50mS initial delay before transmit -} +constexpr int64_t CLOCK_TIMEOUT = 1000; // 1000mS timeout for external clock locking +constexpr float INIT_DELAY = 0.05; // 50mS initial delay before transmit +} // namespace /*********************************************************************** * Test result variables **********************************************************************/ -unsigned long long num_overruns = 0; -unsigned long long num_underruns = 0; -unsigned long long num_rx_samps = 0; -unsigned long long num_tx_samps = 0; +unsigned long long num_overruns = 0; +unsigned long long num_underruns = 0; +unsigned long long num_rx_samps = 0; +unsigned long long num_tx_samps = 0; unsigned long long num_dropped_samps = 0; -unsigned long long num_seq_errors = 0; -unsigned long long num_seqrx_errors = 0; // "D"s +unsigned long long num_seq_errors = 0; +unsigned long long num_seqrx_errors = 0; // "D"s unsigned long long num_late_commands = 0; -unsigned long long num_timeouts_rx = 0; -unsigned long long num_timeouts_tx = 0; +unsigned long long num_timeouts_rx = 0; +unsigned long long num_timeouts_tx = 0; -inline boost::posix_time::time_duration time_delta(const boost::posix_time::ptime &ref_time) +inline boost::posix_time::time_duration time_delta( + const boost::posix_time::ptime& ref_time) { return boost::posix_time::microsec_clock::local_time() - ref_time; } -inline std::string time_delta_str(const boost::posix_time::ptime &ref_time) +inline std::string time_delta_str(const boost::posix_time::ptime& ref_time) { return boost::posix_time::to_simple_string(time_delta(ref_time)); } @@ -57,44 +58,45 @@ inline std::string time_delta_str(const boost::posix_time::ptime &ref_time) /*********************************************************************** * Benchmark RX Rate **********************************************************************/ -void benchmark_rx_rate( - uhd::usrp::multi_usrp::sptr usrp, - const std::string &rx_cpu, - uhd::rx_streamer::sptr rx_stream, - bool random_nsamps, - const boost::posix_time::ptime &start_time, - std::atomic<bool>& burst_timer_elapsed -) { +void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp, + const std::string& rx_cpu, + uhd::rx_streamer::sptr rx_stream, + bool random_nsamps, + const boost::posix_time::ptime& start_time, + std::atomic<bool>& burst_timer_elapsed) +{ uhd::set_thread_priority_safe(); - //print pre-test summary - std::cout << boost::format( - "[%s] Testing receive rate %f Msps on %u channels" - ) % NOW() % (usrp->get_rx_rate()/1e6) % rx_stream->get_num_channels() << std::endl; + // print pre-test summary + std::cout << boost::format("[%s] Testing receive rate %f Msps on %u channels") % NOW() + % (usrp->get_rx_rate() / 1e6) % rx_stream->get_num_channels() + << std::endl; - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::rx_metadata_t md; const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); - std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(rx_cpu)); - std::vector<void *> buffs; + std::vector<char> buff( + max_samps_per_packet * uhd::convert::get_bytes_per_item(rx_cpu)); + std::vector<void*> buffs; for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) - buffs.push_back(&buff.front()); //same buffer for each channel + buffs.push_back(&buff.front()); // same buffer for each channel bool had_an_overflow = false; uhd::time_spec_t last_time; const double rate = usrp->get_rx_rate(); uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY); + cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY); cmd.stream_now = (buffs.size() == 1); rx_stream->issue_stream_cmd(cmd); const float burst_pkt_time = - std::max<float>(0.100f, (2 * max_samps_per_packet/rate)); + std::max<float>(0.100f, (2 * max_samps_per_packet / rate)); float recv_timeout = burst_pkt_time + INIT_DELAY; bool stop_called = false; while (true) { - //if (burst_timer_elapsed.load(boost::memory_order_relaxed) and not stop_called) { + // if (burst_timer_elapsed.load(boost::memory_order_relaxed) and not stop_called) + // { if (burst_timer_elapsed and not stop_called) { rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); stop_called = true; @@ -104,71 +106,78 @@ void benchmark_rx_rate( rx_stream->issue_stream_cmd(cmd); } try { - num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, recv_timeout)*rx_stream->get_num_channels(); + num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, recv_timeout) + * rx_stream->get_num_channels(); recv_timeout = burst_pkt_time; - } - catch (uhd::io_error &e) { + } catch (uhd::io_error& e) { std::cerr << "[" << NOW() << "] Caught an IO exception. " << std::endl; std::cerr << e.what() << std::endl; return; } - //handle the error codes - switch(md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - if (had_an_overflow) { - had_an_overflow = false; - const long dropped_samps = - (md.time_spec - last_time).to_ticks(rate); - if (dropped_samps < 0) { - std::cerr - << "[" << NOW() << "] Timestamp after overrun recovery " - "ahead of error timestamp! Unable to calculate " - "number of dropped samples." - "(Delta: " << dropped_samps << " ticks)\n"; + // handle the error codes + switch (md.error_code) { + case uhd::rx_metadata_t::ERROR_CODE_NONE: + if (had_an_overflow) { + had_an_overflow = false; + const long dropped_samps = (md.time_spec - last_time).to_ticks(rate); + if (dropped_samps < 0) { + std::cerr << "[" << NOW() + << "] Timestamp after overrun recovery " + "ahead of error timestamp! Unable to calculate " + "number of dropped samples." + "(Delta: " + << dropped_samps << " ticks)\n"; + } + num_dropped_samps += std::max<long>(1, dropped_samps); } - num_dropped_samps += std::max<long>(1, dropped_samps); - } - if ((burst_timer_elapsed or stop_called) and md.end_of_burst) { - return; - } - break; - - // ERROR_CODE_OVERFLOW can indicate overflow or sequence error - case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: - last_time = md.time_spec; - had_an_overflow = true; - // check out_of_sequence flag to see if it was a sequence error or overflow - if (!md.out_of_sequence) { - num_overruns++; - } else { - num_seqrx_errors++; - std::cerr << "[" << NOW() << "] Detected Rx sequence error." << std::endl; - } - break; - - case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: - std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << ", restart streaming..."<< std::endl; - num_late_commands++; - // Radio core will be in the idle state. Issue stream command to restart streaming. - cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); - cmd.stream_now = (buffs.size() == 1); - rx_stream->issue_stream_cmd(cmd); - break; - - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - if (burst_timer_elapsed) { - return; - } - std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << ", continuing..." << std::endl; - num_timeouts_rx++; - break; - - // Otherwise, it's an error - default: - std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << std::endl; - std::cerr << "[" << NOW() << "] Unexpected error on recv, continuing..." << std::endl; - break; + if ((burst_timer_elapsed or stop_called) and md.end_of_burst) { + return; + } + break; + + // ERROR_CODE_OVERFLOW can indicate overflow or sequence error + case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: + last_time = md.time_spec; + had_an_overflow = true; + // check out_of_sequence flag to see if it was a sequence error or + // overflow + if (!md.out_of_sequence) { + num_overruns++; + } else { + num_seqrx_errors++; + std::cerr << "[" << NOW() << "] Detected Rx sequence error." + << std::endl; + } + break; + + case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: + std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() + << ", restart streaming..." << std::endl; + num_late_commands++; + // Radio core will be in the idle state. Issue stream command to restart + // streaming. + cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); + cmd.stream_now = (buffs.size() == 1); + rx_stream->issue_stream_cmd(cmd); + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (burst_timer_elapsed) { + return; + } + std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() + << ", continuing..." << std::endl; + num_timeouts_rx++; + break; + + // Otherwise, it's an error + default: + std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() + << std::endl; + std::cerr << "[" << NOW() << "] Unexpected error on recv, continuing..." + << std::endl; + break; } } } @@ -176,71 +185,75 @@ void benchmark_rx_rate( /*********************************************************************** * Benchmark TX Rate **********************************************************************/ -void benchmark_tx_rate( - uhd::usrp::multi_usrp::sptr usrp, - const std::string &tx_cpu, - uhd::tx_streamer::sptr tx_stream, - std::atomic<bool>& burst_timer_elapsed, - const boost::posix_time::ptime &start_time, - bool random_nsamps=false -) { +void benchmark_tx_rate(uhd::usrp::multi_usrp::sptr usrp, + const std::string& tx_cpu, + uhd::tx_streamer::sptr tx_stream, + std::atomic<bool>& burst_timer_elapsed, + const boost::posix_time::ptime& start_time, + bool random_nsamps = false) +{ uhd::set_thread_priority_safe(); - //print pre-test summary - std::cout << boost::format( - "[%s] Testing transmit rate %f Msps on %u channels" - ) % NOW() % (usrp->get_tx_rate()/1e6) % tx_stream->get_num_channels() << std::endl; + // print pre-test summary + std::cout << boost::format("[%s] Testing transmit rate %f Msps on %u channels") + % NOW() % (usrp->get_tx_rate() / 1e6) % tx_stream->get_num_channels() + << std::endl; - //setup variables and allocate buffer + // setup variables and allocate buffer const size_t max_samps_per_packet = tx_stream->get_max_num_samps(); - std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(tx_cpu)); - std::vector<const void *> buffs; + std::vector<char> buff( + max_samps_per_packet * uhd::convert::get_bytes_per_item(tx_cpu)); + std::vector<const void*> buffs; for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) - buffs.push_back(&buff.front()); //same buffer for each channel + buffs.push_back(&buff.front()); // same buffer for each channel // Create the metadata, and populate the time spec at the latest possible moment uhd::tx_metadata_t md; md.has_time_spec = (buffs.size() != 1); - md.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY); + md.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY); if (random_nsamps) { std::srand((unsigned int)time(NULL)); while (not burst_timer_elapsed) { size_t total_num_samps = rand() % max_samps_per_packet; - size_t num_acc_samps = 0; - const float timeout = 1; + size_t num_acc_samps = 0; + const float timeout = 1; usrp->set_time_now(uhd::time_spec_t(0.0)); - while(num_acc_samps < total_num_samps){ - //send a single packet - num_tx_samps += tx_stream->send(buffs, max_samps_per_packet, md, timeout)*tx_stream->get_num_channels(); - num_acc_samps += std::min(total_num_samps-num_acc_samps, tx_stream->get_max_num_samps()); + while (num_acc_samps < total_num_samps) { + // send a single packet + num_tx_samps += tx_stream->send(buffs, max_samps_per_packet, md, timeout) + * tx_stream->get_num_channels(); + num_acc_samps += std::min( + total_num_samps - num_acc_samps, tx_stream->get_max_num_samps()); } } } else { while (not burst_timer_elapsed) { - const size_t num_tx_samps_sent_now = tx_stream->send(buffs, max_samps_per_packet, md)*tx_stream->get_num_channels(); + const size_t num_tx_samps_sent_now = + tx_stream->send(buffs, max_samps_per_packet, md) + * tx_stream->get_num_channels(); num_tx_samps += num_tx_samps_sent_now; if (num_tx_samps_sent_now == 0) { num_timeouts_tx++; if ((num_timeouts_tx % 10000) == 1) { - std::cerr << "[" << NOW() << "] Tx timeouts: " << num_timeouts_tx << std::endl; + std::cerr << "[" << NOW() << "] Tx timeouts: " << num_timeouts_tx + << std::endl; } } md.has_time_spec = false; } } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send(buffs, 0, md); } -void benchmark_tx_rate_async_helper( - uhd::tx_streamer::sptr tx_stream, - const boost::posix_time::ptime &start_time, - std::atomic<bool>& burst_timer_elapsed -) { - //setup variables and allocate buffer +void benchmark_tx_rate_async_helper(uhd::tx_streamer::sptr tx_stream, + const boost::posix_time::ptime& start_time, + std::atomic<bool>& burst_timer_elapsed) +{ + // setup variables and allocate buffer uhd::async_metadata_t async_md; bool exit_flag = false; @@ -255,25 +268,26 @@ void benchmark_tx_rate_async_helper( continue; } - //handle the error codes - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: - return; - - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET: - num_underruns++; - break; - - case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR: - case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST: - num_seq_errors++; - break; + // handle the error codes + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + return; - default: - std::cerr << "[" << NOW() << "] Event code: " << async_md.event_code << std::endl; - std::cerr << "Unexpected event on async recv, continuing..." << std::endl; - break; + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET: + num_underruns++; + break; + + case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR: + case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST: + num_seq_errors++; + break; + + default: + std::cerr << "[" << NOW() << "] Event code: " << async_md.event_code + << std::endl; + std::cerr << "Unexpected event on async recv, continuing..." << std::endl; + break; } } } @@ -281,10 +295,11 @@ void benchmark_tx_rate_async_helper( /*********************************************************************** * Main code + dispatcher **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; std::string rx_subdev, tx_subdev; double duration; @@ -297,7 +312,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::atomic<bool> burst_timer_elapsed(false); size_t overrun_threshold, underrun_threshold, drop_threshold, seq_threshold; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -333,45 +348,52 @@ 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 (vm.count("rx_rate") + vm.count("tx_rate")) == 0){ + // print the help message + if (vm.count("help") or (vm.count("rx_rate") + vm.count("tx_rate")) == 0) { std::cout << boost::format("UHD Benchmark Rate %s") % desc << std::endl; - std::cout << - " Specify --rx_rate for a receive-only test.\n" - " Specify --tx_rate for a transmit-only test.\n" - " Specify both options for a full-duplex test.\n" - << std::endl; + std::cout << " Specify --rx_rate for a receive-only test.\n" + " Specify --tx_rate for a transmit-only test.\n" + " Specify both options for a full-duplex test.\n" + << std::endl; return ~0; } // Random number of samples? if (vm.count("random")) { - std::cout << "Using random number of samples in send() and recv() calls." << std::endl; + std::cout << "Using random number of samples in send() and recv() calls." + << std::endl; random_nsamps = true; } if (vm.count("mode")) { if (vm.count("pps") or vm.count("ref")) { - std::cout << "ERROR: The \"mode\" parameter cannot be used with the \"ref\" and \"pps\" parameters.\n" << std::endl; + std::cout << "ERROR: The \"mode\" parameter cannot be used with the \"ref\" " + "and \"pps\" parameters.\n" + << std::endl; return -1; } else if (mode == "mimo") { ref = pps = "mimo"; - std::cout << "The use of the \"mode\" parameter is deprecated. Please use \"ref\" and \"pps\" parameters instead\n" << std::endl; + std::cout << "The use of the \"mode\" parameter is deprecated. Please use " + "\"ref\" and \"pps\" parameters instead\n" + << std::endl; } } - //create a usrp device + // create a usrp device std::cout << std::endl; uhd::device_addrs_t device_addrs = uhd::device::find(args, uhd::device::USRP); - if (not device_addrs.empty() and device_addrs.at(0).get("type", "") == "usrp1"){ + if (not device_addrs.empty() and device_addrs.at(0).get("type", "") == "usrp1") { std::cerr << "*** Warning! ***" << std::endl; - std::cerr << "Benchmark results will be inaccurate on USRP1 due to insufficient features.\n" << std::endl; + std::cerr << "Benchmark results will be inaccurate on USRP1 due to insufficient " + "features.\n" + << std::endl; } boost::posix_time::ptime start_time(boost::posix_time::microsec_clock::local_time()); - std::cout << boost::format("[%s] Creating the usrp device with: %s...") % NOW() % args << std::endl; + std::cout << boost::format("[%s] Creating the usrp device with: %s...") % NOW() % args + << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); - //always select the subdevice first, the channel mapping affects the other settings + // always select the subdevice first, the channel mapping affects the other settings if (vm.count("rx_subdev")) { usrp->set_rx_subdev_spec(rx_subdev); } @@ -384,34 +406,35 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ boost::thread_group thread_group; - if(vm.count("ref")) - { - if (ref == "mimo") - { + if (vm.count("ref")) { + if (ref == "mimo") { if (num_mboards != 2) { - std::cerr << "ERROR: ref = \"mimo\" implies 2 motherboards; your system has " << num_mboards << " boards" << std::endl; + std::cerr + << "ERROR: ref = \"mimo\" implies 2 motherboards; your system has " + << num_mboards << " boards" << std::endl; return -1; } - usrp->set_clock_source("mimo",1); + usrp->set_clock_source("mimo", 1); } else { usrp->set_clock_source(ref); } - if(ref != "internal") { + if (ref != "internal") { std::cout << "Now confirming lock on clock signals..." << std::endl; bool is_locked = false; auto end_time = - boost::get_system_time() + - boost::posix_time::milliseconds(CLOCK_TIMEOUT); + boost::get_system_time() + boost::posix_time::milliseconds(CLOCK_TIMEOUT); for (int i = 0; i < num_mboards; i++) { - if (ref == "mimo" and i == 0) continue; - while((is_locked = usrp->get_mboard_sensor("ref_locked",i).to_bool()) == false and - boost::get_system_time() < end_time ) - { + if (ref == "mimo" and i == 0) + continue; + while ((is_locked = usrp->get_mboard_sensor("ref_locked", i).to_bool()) + == false + and boost::get_system_time() < end_time) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } if (is_locked == false) { - std::cerr << "ERROR: Unable to confirm clock signal locked on board:" << i << std::endl; + std::cerr << "ERROR: Unable to confirm clock signal locked on board:" + << i << std::endl; return -1; } is_locked = false; @@ -419,22 +442,22 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } } - if(vm.count("pps")) - { - if(pps == "mimo") - { - if (num_mboards != 2) { - std::cerr << "ERROR: ref = \"mimo\" implies 2 motherboards; your system has " << num_mboards << " boards" << std::endl; - return -1; - } - //make mboard 1 a slave over the MIMO Cable - usrp->set_time_source("mimo", 1); - } else { - usrp->set_time_source(pps); - } + if (vm.count("pps")) { + if (pps == "mimo") { + if (num_mboards != 2) { + std::cerr + << "ERROR: ref = \"mimo\" implies 2 motherboards; your system has " + << num_mboards << " boards" << std::endl; + return -1; + } + // make mboard 1 a slave over the MIMO Cable + usrp->set_time_source("mimo", 1); + } else { + usrp->set_time_source(pps); + } } - //check that the device has sufficient RX and TX channels available + // check that the device has sufficient RX and TX channels available std::vector<std::string> channel_strings; std::vector<size_t> rx_channel_nums; if (vm.count("rx_rate")) { @@ -470,7 +493,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } } - std::cout << boost::format("[%s] Setting device timestamp to 0...") % NOW() << std::endl; + std::cout << boost::format("[%s] Setting device timestamp to 0...") % NOW() + << std::endl; if (pps == "mimo" or ref == "mimo") { // only set the master's time, the slave's is automatically sync'd usrp->set_time_now(uhd::time_spec_t(0.0), 0); @@ -484,144 +508,103 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp->set_time_now(0.0); } - //spawn the receive test thread - if (vm.count("rx_rate")){ + // spawn the receive test thread + if (vm.count("rx_rate")) { usrp->set_rx_rate(rx_rate); - //create a receive streamer + // create a receive streamer uhd::stream_args_t stream_args(rx_cpu, rx_otw); - stream_args.channels = rx_channel_nums; + stream_args.channels = rx_channel_nums; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - auto rx_thread = thread_group.create_thread([=, &burst_timer_elapsed](){ + auto rx_thread = thread_group.create_thread([=, &burst_timer_elapsed]() { benchmark_rx_rate( - usrp, - rx_cpu, - rx_stream, - random_nsamps, - start_time, - burst_timer_elapsed - ); + usrp, rx_cpu, rx_stream, random_nsamps, start_time, burst_timer_elapsed); }); uhd::set_thread_name(rx_thread, "bmark_rx_stream"); } - //spawn the transmit test thread - if (vm.count("tx_rate")){ + // spawn the transmit test thread + if (vm.count("tx_rate")) { usrp->set_tx_rate(tx_rate); - //create a transmit streamer + // create a transmit streamer uhd::stream_args_t stream_args(tx_cpu, tx_otw); - stream_args.channels = tx_channel_nums; + stream_args.channels = tx_channel_nums; uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - auto tx_thread = thread_group.create_thread([=, &burst_timer_elapsed](){ + auto tx_thread = thread_group.create_thread([=, &burst_timer_elapsed]() { benchmark_tx_rate( - usrp, - tx_cpu, - tx_stream, - burst_timer_elapsed, - start_time, - random_nsamps - ); + usrp, tx_cpu, tx_stream, burst_timer_elapsed, start_time, random_nsamps); }); uhd::set_thread_name(tx_thread, "bmark_tx_stream"); - auto tx_async_thread = thread_group.create_thread([=, &burst_timer_elapsed](){ - benchmark_tx_rate_async_helper( - tx_stream, - start_time, - burst_timer_elapsed - ); + auto tx_async_thread = thread_group.create_thread([=, &burst_timer_elapsed]() { + benchmark_tx_rate_async_helper(tx_stream, start_time, burst_timer_elapsed); }); uhd::set_thread_name(tx_async_thread, "bmark_tx_helper"); } - //sleep for the required duration + // sleep for the required duration const bool wait_for_multichan = (rx_channel_nums.size() <= 1 and tx_channel_nums.size() <= 1); - const int64_t secs = - int64_t(duration + (wait_for_multichan ? 0 : INIT_DELAY * 1000)); - const int64_t usecs = int64_t((duration - secs)*1e6); + const int64_t secs = int64_t(duration + (wait_for_multichan ? 0 : INIT_DELAY * 1000)); + const int64_t usecs = int64_t((duration - secs) * 1e6); std::this_thread::sleep_for( - std::chrono::seconds(secs) + - std::chrono::microseconds(usecs) - ); + std::chrono::seconds(secs) + std::chrono::microseconds(usecs)); - //interrupt and join the threads + // interrupt and join the threads burst_timer_elapsed = true; thread_group.join_all(); std::cout << "[" << NOW() << "] Benchmark complete." << std::endl << std::endl; - //print summary + // print summary const std::string threshold_err(" ERROR: Exceeds threshold!"); - const bool overrun_threshold_err = - vm.count("overrun-threshold") and - num_overruns > overrun_threshold; - const bool underrun_threshold_err = - vm.count("underrun-threshold") and - num_underruns > underrun_threshold; - const bool drop_threshold_err = - vm.count("drop-threshold") and - num_seqrx_errors > drop_threshold; - const bool seq_threshold_err = - vm.count("seq-threshold") and - num_seq_errors > seq_threshold; + const bool overrun_threshold_err = vm.count("overrun-threshold") + and num_overruns > overrun_threshold; + const bool underrun_threshold_err = vm.count("underrun-threshold") + and num_underruns > underrun_threshold; + const bool drop_threshold_err = vm.count("drop-threshold") + and num_seqrx_errors > drop_threshold; + const bool seq_threshold_err = vm.count("seq-threshold") + and num_seq_errors > seq_threshold; std::cout << std::endl - << boost::format( - "Benchmark rate summary:\n" - " Num received samples: %u\n" - " Num dropped samples: %u\n" - " Num overruns detected: %u\n" - " Num transmitted samples: %u\n" - " Num sequence errors (Tx): %u\n" - " Num sequence errors (Rx): %u\n" - " Num underruns detected: %u\n" - " Num late commands: %u\n" - " Num timeouts (Tx): %u\n" - " Num timeouts (Rx): %u\n" - ) % num_rx_samps - % num_dropped_samps - % num_overruns - % num_tx_samps - % num_seq_errors - % num_seqrx_errors - % num_underruns - % num_late_commands - % num_timeouts_tx - % num_timeouts_rx - << std::endl; - //finished + << boost::format("Benchmark rate summary:\n" + " Num received samples: %u\n" + " Num dropped samples: %u\n" + " Num overruns detected: %u\n" + " Num transmitted samples: %u\n" + " Num sequence errors (Tx): %u\n" + " Num sequence errors (Rx): %u\n" + " Num underruns detected: %u\n" + " Num late commands: %u\n" + " Num timeouts (Tx): %u\n" + " Num timeouts (Rx): %u\n") + % num_rx_samps % num_dropped_samps % num_overruns % num_tx_samps + % num_seq_errors % num_seqrx_errors % num_underruns + % num_late_commands % num_timeouts_tx % num_timeouts_rx + << std::endl; + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; - if (overrun_threshold_err - || underrun_threshold_err - || drop_threshold_err - || seq_threshold_err) { + if (overrun_threshold_err || underrun_threshold_err || drop_threshold_err + || seq_threshold_err) { std::cout << "The following error thresholds were exceeded:\n"; if (overrun_threshold_err) { - std::cout - << boost::format(" * Overruns (%d/%d)") - % num_overruns - % overrun_threshold - << std::endl; + std::cout << boost::format(" * Overruns (%d/%d)") % num_overruns + % overrun_threshold + << std::endl; } if (underrun_threshold_err) { - std::cout - << boost::format(" * Underruns (%d/%d)") - % num_underruns - % underrun_threshold - << std::endl; + std::cout << boost::format(" * Underruns (%d/%d)") % num_underruns + % underrun_threshold + << std::endl; } if (drop_threshold_err) { - std::cout - << boost::format(" * Dropped packets (RX) (%d/%d)") - % num_seqrx_errors - % drop_threshold - << std::endl; + std::cout << boost::format(" * Dropped packets (RX) (%d/%d)") + % num_seqrx_errors % drop_threshold + << std::endl; } if (seq_threshold_err) { - std::cout - << boost::format(" * Dropped packets (TX) (%d/%d)") - % num_seq_errors - % seq_threshold - << std::endl; + std::cout << boost::format(" * Dropped packets (TX) (%d/%d)") + % num_seq_errors % seq_threshold + << std::endl; } return EXIT_FAILURE; } diff --git a/host/examples/benchmark_streamer.cpp b/host/examples/benchmark_streamer.cpp index 609e50788..44851825a 100644 --- a/host/examples/benchmark_streamer.cpp +++ b/host/examples/benchmark_streamer.cpp @@ -4,27 +4,28 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/device3.hpp> #include <uhd/convert.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> +#include <uhd/device3.hpp> #include <uhd/rfnoc/block_ctrl.hpp> -#include <uhd/rfnoc/null_block_ctrl.hpp> #include <uhd/rfnoc/ddc_block_ctrl.hpp> #include <uhd/rfnoc/duc_block_ctrl.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> +#include <uhd/rfnoc/null_block_ctrl.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/algorithm/string/trim_all.hpp> +#include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <chrono> +#include <deque> +#include <iomanip> #include <iostream> #include <sstream> -#include <iomanip> #include <thread> -#include <chrono> -#include <deque> namespace po = boost::program_options; -struct traffic_counter_values { +struct traffic_counter_values +{ uint64_t clock_cycles; uint64_t xbar_to_shell_xfer_count; @@ -40,71 +41,80 @@ struct traffic_counter_values { uint64_t ce_to_shell_pkt_count; }; -struct host_measurement_values { +struct host_measurement_values +{ double seconds; uint64_t num_samples; uint64_t num_packets; uint64_t spp; }; -struct test_results { +struct test_results +{ std::vector<traffic_counter_values> traffic_counter; host_measurement_values host; }; -struct noc_block_endpoint { +struct noc_block_endpoint +{ std::string block_id; size_t port; }; -void enable_traffic_counters( - uhd::property_tree::sptr tree, - uhd::fs_path noc_block_root -) { - tree->access<uint64_t>(noc_block_root/"traffic_counter/enable").set(true); +void enable_traffic_counters(uhd::property_tree::sptr tree, uhd::fs_path noc_block_root) +{ + tree->access<uint64_t>(noc_block_root / "traffic_counter/enable").set(true); } -void disable_traffic_counters( - uhd::property_tree::sptr tree, - uhd::fs_path noc_block_root -) { - tree->access<uint64_t>(noc_block_root/"traffic_counter/enable").set(false); +void disable_traffic_counters(uhd::property_tree::sptr tree, uhd::fs_path noc_block_root) +{ + tree->access<uint64_t>(noc_block_root / "traffic_counter/enable").set(false); } traffic_counter_values read_traffic_counters( - uhd::property_tree::sptr tree, - uhd::fs_path noc_block_root -) { - uhd::fs_path root = noc_block_root/"traffic_counter"; + uhd::property_tree::sptr tree, uhd::fs_path noc_block_root) +{ + uhd::fs_path root = noc_block_root / "traffic_counter"; traffic_counter_values vals; - vals.clock_cycles = tree->access<uint64_t>(root/"bus_clock_ticks").get(); + vals.clock_cycles = tree->access<uint64_t>(root / "bus_clock_ticks").get(); - vals.xbar_to_shell_pkt_count = tree->access<uint64_t>(root/"xbar_to_shell_pkt_count").get(); - vals.xbar_to_shell_xfer_count = tree->access<uint64_t>(root/"xbar_to_shell_xfer_count").get(); + vals.xbar_to_shell_pkt_count = + tree->access<uint64_t>(root / "xbar_to_shell_pkt_count").get(); + vals.xbar_to_shell_xfer_count = + tree->access<uint64_t>(root / "xbar_to_shell_xfer_count").get(); - vals.shell_to_xbar_pkt_count = tree->access<uint64_t>(root/"shell_to_xbar_pkt_count").get(); - vals.shell_to_xbar_xfer_count = tree->access<uint64_t>(root/"shell_to_xbar_xfer_count").get(); + vals.shell_to_xbar_pkt_count = + tree->access<uint64_t>(root / "shell_to_xbar_pkt_count").get(); + vals.shell_to_xbar_xfer_count = + tree->access<uint64_t>(root / "shell_to_xbar_xfer_count").get(); - vals.shell_to_ce_pkt_count = tree->access<uint64_t>(root/"shell_to_ce_pkt_count").get(); - vals.shell_to_ce_xfer_count = tree->access<uint64_t>(root/"shell_to_ce_xfer_count").get(); + vals.shell_to_ce_pkt_count = + tree->access<uint64_t>(root / "shell_to_ce_pkt_count").get(); + vals.shell_to_ce_xfer_count = + tree->access<uint64_t>(root / "shell_to_ce_xfer_count").get(); - vals.ce_to_shell_pkt_count = tree->access<uint64_t>(root/"ce_to_shell_pkt_count").get(); - vals.ce_to_shell_xfer_count = tree->access<uint64_t>(root/"ce_to_shell_xfer_count").get(); + vals.ce_to_shell_pkt_count = + tree->access<uint64_t>(root / "ce_to_shell_pkt_count").get(); + vals.ce_to_shell_xfer_count = + tree->access<uint64_t>(root / "ce_to_shell_xfer_count").get(); return vals; } -void print_traffic_counters( - const traffic_counter_values& vals -) { +void print_traffic_counters(const traffic_counter_values& vals) +{ std::cout << "Clock cycles: " << vals.clock_cycles << std::endl; - std::cout << "Xbar to shell pkt count: " << vals.xbar_to_shell_pkt_count << std::endl; - std::cout << "Xbar to shell xfer count: " << vals.xbar_to_shell_xfer_count << std::endl; + std::cout << "Xbar to shell pkt count: " << vals.xbar_to_shell_pkt_count + << std::endl; + std::cout << "Xbar to shell xfer count: " << vals.xbar_to_shell_xfer_count + << std::endl; - std::cout << "Shell to xbar pkt count: " << vals.shell_to_xbar_pkt_count << std::endl; - std::cout << "Shell to xbar xfer count: " << vals.shell_to_xbar_xfer_count << std::endl; + std::cout << "Shell to xbar pkt count: " << vals.shell_to_xbar_pkt_count + << std::endl; + std::cout << "Shell to xbar xfer count: " << vals.shell_to_xbar_xfer_count + << std::endl; std::cout << "Shell to CE pkt count: " << vals.shell_to_ce_pkt_count << std::endl; std::cout << "Shell to CE xfer count: " << vals.shell_to_ce_xfer_count << std::endl; @@ -113,173 +123,189 @@ void print_traffic_counters( std::cout << "CE to shell xfer count: " << vals.ce_to_shell_xfer_count << std::endl; } -void print_rx_statistics( - const traffic_counter_values& vals, - const double bus_clk_freq -) { - const double bus_time_elapsed = vals.clock_cycles / bus_clk_freq; +void print_rx_statistics(const traffic_counter_values& vals, const double bus_clk_freq) +{ + const double bus_time_elapsed = vals.clock_cycles / bus_clk_freq; const uint64_t num_ce_packets_read = vals.ce_to_shell_pkt_count; - const uint64_t num_ce_samples_read = (vals.ce_to_shell_xfer_count - num_ce_packets_read)*2; + const uint64_t num_ce_samples_read = + (vals.ce_to_shell_xfer_count - num_ce_packets_read) * 2; - const uint64_t num_non_data_packets_read = vals.shell_to_xbar_pkt_count - num_ce_packets_read; - const double rx_data_packet_ratio = (double)num_ce_packets_read/num_non_data_packets_read; + const uint64_t num_non_data_packets_read = + vals.shell_to_xbar_pkt_count - num_ce_packets_read; + const double rx_data_packet_ratio = + (double)num_ce_packets_read / num_non_data_packets_read; - const double calculated_throughput = num_ce_samples_read/bus_time_elapsed; + const double calculated_throughput = num_ce_samples_read / bus_time_elapsed; std::cout << "Time elapsed: " << bus_time_elapsed << " s" << std::endl; std::cout << "Samples read: " << num_ce_samples_read << std::endl; std::cout << "Data packets read: " << num_ce_packets_read << std::endl; - std::cout << "RX data packet ratio: " << rx_data_packet_ratio << " data to non-data packets" << std::endl; - std::cout << "Calculated throughput: " << calculated_throughput/1e6 << " Msps" << std::endl; + std::cout << "RX data packet ratio: " << rx_data_packet_ratio + << " data to non-data packets" << std::endl; + std::cout << "Calculated throughput: " << calculated_throughput / 1e6 << " Msps" + << std::endl; } -void print_tx_statistics( - const traffic_counter_values& vals, - const double bus_clk_freq -) { - const double bus_time_elapsed = vals.clock_cycles / bus_clk_freq; +void print_tx_statistics(const traffic_counter_values& vals, const double bus_clk_freq) +{ + const double bus_time_elapsed = vals.clock_cycles / bus_clk_freq; const uint64_t num_ce_packets_written = vals.shell_to_ce_pkt_count; - const uint64_t num_ce_samples_written = (vals.shell_to_ce_xfer_count - num_ce_packets_written)*2; + const uint64_t num_ce_samples_written = + (vals.shell_to_ce_xfer_count - num_ce_packets_written) * 2; - const uint64_t num_non_data_packets_written = vals.xbar_to_shell_pkt_count - num_ce_packets_written; - const double tx_data_packet_ratio = (double)num_ce_packets_written/num_non_data_packets_written; + const uint64_t num_non_data_packets_written = + vals.xbar_to_shell_pkt_count - num_ce_packets_written; + const double tx_data_packet_ratio = + (double)num_ce_packets_written / num_non_data_packets_written; - const double calculated_throughput = num_ce_samples_written/bus_time_elapsed; + const double calculated_throughput = num_ce_samples_written / bus_time_elapsed; std::cout << "Time elapsed: " << bus_time_elapsed << " s" << std::endl; std::cout << "Samples written: " << num_ce_samples_written << std::endl; std::cout << "Data packets written: " << num_ce_packets_written << std::endl; - std::cout << "TX data packet ratio: " << tx_data_packet_ratio << " data to non-data packets" << std::endl; - std::cout << "Calculated throughput: " << calculated_throughput/1e6 << " Msps" << std::endl; + std::cout << "TX data packet ratio: " << tx_data_packet_ratio + << " data to non-data packets" << std::endl; + std::cout << "Calculated throughput: " << calculated_throughput / 1e6 << " Msps" + << std::endl; } -void print_utilization_statistics( - const traffic_counter_values& vals -) { - const double rx_data_cycles = vals.ce_to_shell_xfer_count - vals.ce_to_shell_pkt_count; +void print_utilization_statistics(const traffic_counter_values& vals) +{ + const double rx_data_cycles = + vals.ce_to_shell_xfer_count - vals.ce_to_shell_pkt_count; const double rx_idle_cycles = vals.clock_cycles - vals.shell_to_xbar_xfer_count; const double rx_data_header_cycles = vals.ce_to_shell_pkt_count; - const double rx_other_cycles = vals.shell_to_xbar_xfer_count - vals.ce_to_shell_xfer_count; + const double rx_other_cycles = + vals.shell_to_xbar_xfer_count - vals.ce_to_shell_xfer_count; - const double rx_data_util = rx_data_cycles / vals.clock_cycles*100; - const double rx_idle_util = rx_idle_cycles / vals.clock_cycles*100; + const double rx_data_util = rx_data_cycles / vals.clock_cycles * 100; + const double rx_idle_util = rx_idle_cycles / vals.clock_cycles * 100; const double rx_data_header_util = rx_data_header_cycles / vals.clock_cycles * 100; - const double rx_other_util = rx_other_cycles / vals.clock_cycles * 100; + const double rx_other_util = rx_other_cycles / vals.clock_cycles * 100; std::cout << "RX utilization:" << std::endl; std::cout << " data: " << rx_data_util << " %" << std::endl; std::cout << " idle: " << rx_idle_util << " %" << std::endl; std::cout << " data header: " << rx_data_header_util << " %" << std::endl; - std::cout << " other: " << rx_other_util << " % (flow control, register I/O)" << std::endl; + std::cout << " other: " << rx_other_util << " % (flow control, register I/O)" + << std::endl; std::cout << std::endl; - const double tx_data_cycles = vals.shell_to_ce_xfer_count - vals.shell_to_ce_pkt_count; + const double tx_data_cycles = + vals.shell_to_ce_xfer_count - vals.shell_to_ce_pkt_count; const double tx_idle_cycles = vals.clock_cycles - vals.xbar_to_shell_xfer_count; const double tx_data_header_cycles = vals.shell_to_ce_pkt_count; - const double tx_other_cycles = vals.xbar_to_shell_xfer_count - vals.shell_to_ce_xfer_count; + const double tx_other_cycles = + vals.xbar_to_shell_xfer_count - vals.shell_to_ce_xfer_count; - const double tx_data_util = tx_data_cycles / vals.clock_cycles*100; - const double tx_idle_util = tx_idle_cycles / vals.clock_cycles*100; + const double tx_data_util = tx_data_cycles / vals.clock_cycles * 100; + const double tx_idle_util = tx_idle_cycles / vals.clock_cycles * 100; const double tx_data_header_util = tx_data_header_cycles / vals.clock_cycles * 100; - const double tx_other_util = tx_other_cycles / vals.clock_cycles * 100; + const double tx_other_util = tx_other_cycles / vals.clock_cycles * 100; std::cout << "TX utilization:" << std::endl; std::cout << " data: " << tx_data_util << " %" << std::endl; std::cout << " idle: " << tx_idle_util << " %" << std::endl; std::cout << " data header: " << tx_data_header_util << " %" << std::endl; - std::cout << " other: " << tx_other_util << " % (flow control, register I/O)" << std::endl; + std::cout << " other: " << tx_other_util << " % (flow control, register I/O)" + << std::endl; } -void print_rx_results( - const test_results& results, - double bus_clk_freq -) { - std::cout << "------------------------------------------------------------------" << std::endl; - std::cout << "------------------- Benchmarking rx stream -----------------------" << std::endl; - std::cout << "------------------------------------------------------------------" << std::endl; +void print_rx_results(const test_results& results, double bus_clk_freq) +{ + std::cout << "------------------------------------------------------------------" + << std::endl; + std::cout << "------------------- Benchmarking rx stream -----------------------" + << std::endl; + std::cout << "------------------------------------------------------------------" + << std::endl; std::cout << "RX samples per packet: " << results.host.spp << std::endl; std::cout << std::endl; for (const auto& tc : results.traffic_counter) { - std::cout << "------------------ Traffic counter values ------------------------" << std::endl; + std::cout << "------------------ Traffic counter values ------------------------" + << std::endl; print_traffic_counters(tc); std::cout << std::endl; - std::cout << "------------ Values calculated from traffic counters -------------" << std::endl; + std::cout << "------------ Values calculated from traffic counters -------------" + << std::endl; print_rx_statistics(tc, bus_clk_freq); std::cout << std::endl; print_utilization_statistics(tc); std::cout << std::endl; } - std::cout << "--------------------- Host measurements --------------------------" << std::endl; + std::cout << "--------------------- Host measurements --------------------------" + << std::endl; std::cout << "Time elapsed: " << results.host.seconds << " s" << std::endl; std::cout << "Samples read: " << results.host.num_samples << std::endl; std::cout << "Data packets read: " << results.host.num_packets << std::endl; - std::cout << "Calculated throughput: " << results.host.num_samples / results.host.seconds / 1e6 << " Msps" << std::endl; + std::cout << "Calculated throughput: " + << results.host.num_samples / results.host.seconds / 1e6 << " Msps" + << std::endl; } -void print_tx_results( - const test_results& results, - const double bus_clk_freq -) { - std::cout << "------------------------------------------------------------------" << std::endl; - std::cout << "------------------- Benchmarking tx stream -----------------------" << std::endl; - std::cout << "------------------------------------------------------------------" << std::endl; +void print_tx_results(const test_results& results, const double bus_clk_freq) +{ + std::cout << "------------------------------------------------------------------" + << std::endl; + std::cout << "------------------- Benchmarking tx stream -----------------------" + << std::endl; + std::cout << "------------------------------------------------------------------" + << std::endl; std::cout << "TX samples per packet: " << results.host.spp << std::endl; std::cout << std::endl; for (const auto& tc : results.traffic_counter) { - std::cout << "------------------ Traffic counter values ------------------------" << std::endl; + std::cout << "------------------ Traffic counter values ------------------------" + << std::endl; print_traffic_counters(tc); std::cout << std::endl; - std::cout << "------------ Values calculated from traffic counters -------------" << std::endl; + std::cout << "------------ Values calculated from traffic counters -------------" + << std::endl; print_tx_statistics(tc, bus_clk_freq); std::cout << std::endl; print_utilization_statistics(tc); std::cout << std::endl; } - std::cout << "--------------------- Host measurements --------------------------" << std::endl; + std::cout << "--------------------- Host measurements --------------------------" + << std::endl; std::cout << "Time elapsed: " << results.host.seconds << " s" << std::endl; std::cout << "Samples written: " << results.host.num_samples << std::endl; std::cout << "Data packets written: " << results.host.num_packets << std::endl; - std::cout << "Calculated throughput: " << results.host.num_samples / results.host.seconds / 1e6 << " Msps" << std::endl; + std::cout << "Calculated throughput: " + << results.host.num_samples / results.host.seconds / 1e6 << " Msps" + << std::endl; } -void configure_ddc( - uhd::device3::sptr usrp, - const std::string& ddcid, - double ddc_decim -) { +void configure_ddc(uhd::device3::sptr usrp, const std::string& ddcid, double ddc_decim) +{ auto ddc_ctrl = usrp->get_block_ctrl<uhd::rfnoc::ddc_block_ctrl>(ddcid); ddc_ctrl->set_arg<double>("input_rate", 1, 0); - ddc_ctrl->set_arg<double>("output_rate", 1/ddc_decim, 0); + ddc_ctrl->set_arg<double>("output_rate", 1 / ddc_decim, 0); double actual_rate = ddc_ctrl->get_arg<double>("output_rate", 0); - std::cout << "Actual DDC decimation: " << 1/actual_rate << std::endl; + std::cout << "Actual DDC decimation: " << 1 / actual_rate << std::endl; } -void configure_duc( - uhd::device3::sptr usrp, - const std::string& ducid, - double duc_interp -) { +void configure_duc(uhd::device3::sptr usrp, const std::string& ducid, double duc_interp) +{ auto duc_ctrl = usrp->get_block_ctrl<uhd::rfnoc::duc_block_ctrl>(ducid); duc_ctrl->set_arg<double>("output_rate", 1, 0); - duc_ctrl->set_arg<double>("input_rate", 1/duc_interp, 0); + duc_ctrl->set_arg<double>("input_rate", 1 / duc_interp, 0); double actual_rate = duc_ctrl->get_arg<double>("input_rate", 0); - std::cout << "Actual DUC interpolation: " << 1/actual_rate << std::endl; + std::cout << "Actual DUC interpolation: " << 1 / actual_rate << std::endl; } -uhd::rx_streamer::sptr configure_rx_streamer( - uhd::device3::sptr usrp, +uhd::rx_streamer::sptr configure_rx_streamer(uhd::device3::sptr usrp, const std::string null_id, const std::string splitter_id, const std::vector<std::vector<noc_block_endpoint>>& noc_blocks, const size_t spp, - const std::string& format -) { + const std::string& format) +{ std::cout << "Configuring rx stream with" << std::endl; std::cout << " Null ID: " << null_id << std::endl; if (not splitter_id.empty()) { @@ -289,8 +315,8 @@ uhd::rx_streamer::sptr configure_rx_streamer( if (noc_blocks[i].size() > 0) { std::cout << " Channel " << i << std::endl; for (const auto& b : noc_blocks[i]) { - std::cout << " Block ID: " << b.block_id - << ", port: " << b.port << std::endl; + std::cout << " Block ID: " << b.block_id << ", port: " << b.port + << std::endl; } } } @@ -308,8 +334,7 @@ uhd::rx_streamer::sptr configure_rx_streamer( if (noc_blocks.size() == 1) { // No splitter required endpoints = {{null_id, 0}}; - } - else { + } else { // Connect to splitter rx_graph->connect(null_id, splitter_id); @@ -326,12 +351,9 @@ uhd::rx_streamer::sptr configure_rx_streamer( const auto& noc_block = noc_blocks[i][j]; rx_graph->connect( - endpoint_id, - endpoint_port, - noc_block.block_id, - noc_block.port); + endpoint_id, endpoint_port, noc_block.block_id, noc_block.port); - endpoint_id = noc_block.block_id; + endpoint_id = noc_block.block_id; endpoint_port = noc_block.port; } @@ -348,32 +370,32 @@ uhd::rx_streamer::sptr configure_rx_streamer( // Configure null source auto null_ctrl = usrp->get_block_ctrl<uhd::rfnoc::null_block_ctrl>(null_id); - const size_t otw_bytes_per_item = uhd::convert::get_bytes_per_item(stream_args.otw_format); + const size_t otw_bytes_per_item = + uhd::convert::get_bytes_per_item(stream_args.otw_format); const size_t samps_per_packet = rx_stream->get_max_num_samps(); null_ctrl->set_arg<int>("line_rate", 0); - null_ctrl->set_arg<int>("bpp", samps_per_packet*otw_bytes_per_item); + null_ctrl->set_arg<int>("bpp", samps_per_packet * otw_bytes_per_item); return rx_stream; } -test_results benchmark_rx_streamer( - uhd::device3::sptr usrp, +test_results benchmark_rx_streamer(uhd::device3::sptr usrp, uhd::rx_streamer::sptr rx_stream, const std::string& nullid, const double duration, - const std::string& format -) { + const std::string& format) +{ auto null_src_ctrl = usrp->get_block_ctrl<uhd::rfnoc::null_block_ctrl>(nullid); // Allocate buffer const size_t cpu_bytes_per_item = uhd::convert::get_bytes_per_item(format); - const size_t samps_per_packet = rx_stream->get_max_num_samps(); + const size_t samps_per_packet = rx_stream->get_max_num_samps(); const size_t num_channels = rx_stream->get_num_channels(); std::vector<std::vector<uint8_t>> buffer(num_channels); - std::vector<void *> buffers; + std::vector<void*> buffers; for (size_t i = 0; i < num_channels; i++) { - buffer[i].resize(samps_per_packet*cpu_bytes_per_item); + buffer[i].resize(samps_per_packet * cpu_bytes_per_item); buffers.push_back(&buffer[i].front()); } @@ -387,29 +409,27 @@ test_results benchmark_rx_streamer( const std::chrono::duration<double> requested_duration(duration); const auto start_time = std::chrono::steady_clock::now(); - auto current_time = start_time; + auto current_time = start_time; - uint64_t num_rx_samps = 0; + uint64_t num_rx_samps = 0; uint64_t num_rx_packets = 0; uhd::rx_metadata_t md; while (current_time - start_time < requested_duration) { const size_t packets_per_iteration = 1000; - for (size_t i = 0; i < packets_per_iteration; i++){ + for (size_t i = 0; i < packets_per_iteration; i++) { num_rx_samps += rx_stream->recv(buffers, samps_per_packet, md, 1.0); if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { continue; - } - else if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { + } else if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { std::cout << "[ERROR] Receive timeout, aborting." << std::endl; break; - } - else { - std::cout << std::string("[ERROR] Receiver error: ") - << md.strerror() << std::endl; + } else { + std::cout << std::string("[ERROR] Receiver error: ") << md.strerror() + << std::endl; break; } } @@ -424,31 +444,29 @@ test_results benchmark_rx_streamer( null_src_ctrl->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); test_results results; - results.traffic_counter.push_back( - read_traffic_counters( - usrp->get_tree(), null_src_ctrl->get_block_id().get_tree_root())); + results.traffic_counter.push_back(read_traffic_counters( + usrp->get_tree(), null_src_ctrl->get_block_id().get_tree_root())); - const std::chrono::duration<double> elapsed_time(current_time-start_time); - results.host.seconds = elapsed_time.count(); + const std::chrono::duration<double> elapsed_time(current_time - start_time); + results.host.seconds = elapsed_time.count(); results.host.num_samples = num_rx_samps; results.host.num_packets = num_rx_packets; - results.host.spp = samps_per_packet; + results.host.spp = samps_per_packet; return results; } -uhd::tx_streamer::sptr configure_tx_streamer( - uhd::device3::sptr usrp, +uhd::tx_streamer::sptr configure_tx_streamer(uhd::device3::sptr usrp, const std::vector<std::vector<noc_block_endpoint>> noc_blocks, const size_t spp, - const std::string& format -) { + const std::string& format) +{ std::cout << "Configuring tx stream with" << std::endl; for (size_t i = 0; i < noc_blocks.size(); i++) { std::cout << " Channel " << i << std::endl; for (const auto& b : noc_blocks[i]) { - std::cout << " Block ID: " << b.block_id - << ", port: " << b.port << std::endl; + std::cout << " Block ID: " << b.block_id << ", port: " << b.port + << std::endl; } } @@ -470,12 +488,9 @@ uhd::tx_streamer::sptr configure_tx_streamer( if (j != 0) { tx_graph->connect( - noc_block.block_id, - noc_block.port, - endpoint_id, - endpoint_port); + noc_block.block_id, noc_block.port, endpoint_id, endpoint_port); } - endpoint_id = noc_block.block_id; + endpoint_id = noc_block.block_id; endpoint_port = noc_block.port; } @@ -494,28 +509,26 @@ uhd::tx_streamer::sptr configure_tx_streamer( return tx_stream; } -test_results benchmark_tx_streamer( - uhd::device3::sptr usrp, +test_results benchmark_tx_streamer(uhd::device3::sptr usrp, uhd::tx_streamer::sptr tx_stream, const std::vector<std::string>& null_ids, const double duration, - const std::string& format -) { + const std::string& format) +{ std::vector<boost::shared_ptr<uhd::rfnoc::null_block_ctrl>> null_ctrls; for (const auto& id : null_ids) { - null_ctrls.push_back( - usrp->get_block_ctrl<uhd::rfnoc::null_block_ctrl>(id)); + null_ctrls.push_back(usrp->get_block_ctrl<uhd::rfnoc::null_block_ctrl>(id)); } // Allocate buffer const size_t cpu_bytes_per_item = uhd::convert::get_bytes_per_item(format); - const size_t samps_per_packet = tx_stream->get_max_num_samps(); + const size_t samps_per_packet = tx_stream->get_max_num_samps(); const size_t num_channels = tx_stream->get_num_channels(); std::vector<std::vector<uint8_t>> buffer(num_channels); - std::vector<void *> buffers; + std::vector<void*> buffers; for (size_t i = 0; i < num_channels; i++) { - buffer[i].resize(samps_per_packet*cpu_bytes_per_item); + buffer[i].resize(samps_per_packet * cpu_bytes_per_item); buffers.push_back(&buffer[i].front()); } @@ -525,18 +538,18 @@ test_results benchmark_tx_streamer( } // Stream some packets - uint64_t num_tx_samps = 0; + uint64_t num_tx_samps = 0; uint64_t num_tx_packets = 0; uhd::tx_metadata_t md; const std::chrono::duration<double> requested_duration(duration); const auto start_time = std::chrono::steady_clock::now(); - auto current_time = start_time; + auto current_time = start_time; while (current_time - start_time < requested_duration) { const size_t packets_per_iteration = 1000; - for (size_t i = 0; i < packets_per_iteration; i++){ + for (size_t i = 0; i < packets_per_iteration; i++) { num_tx_samps += tx_stream->send(buffers, samps_per_packet, md); } @@ -555,23 +568,21 @@ test_results benchmark_tx_streamer( test_results results; for (auto& null_ctrl : null_ctrls) { - results.traffic_counter.push_back( - read_traffic_counters( - usrp->get_tree(), null_ctrl->get_block_id().get_tree_root())); + results.traffic_counter.push_back(read_traffic_counters( + usrp->get_tree(), null_ctrl->get_block_id().get_tree_root())); } - const std::chrono::duration<double> elapsed_time(current_time-start_time); - results.host.seconds = elapsed_time.count(); + const std::chrono::duration<double> elapsed_time(current_time - start_time); + results.host.seconds = elapsed_time.count(); results.host.num_samples = num_tx_samps; results.host.num_packets = num_tx_packets; - results.host.spp = samps_per_packet; + results.host.spp = samps_per_packet; return results; } -std::vector<std::string> parse_csv( - const std::string& list -) { +std::vector<std::string> parse_csv(const std::string& list) +{ std::vector<std::string> result; std::istringstream input(list); @@ -585,31 +596,29 @@ std::vector<std::string> parse_csv( return result; } -std::deque<noc_block_endpoint> create_noc_block_queue( - const size_t num_blocks, +std::deque<noc_block_endpoint> create_noc_block_queue(const size_t num_blocks, const std::string& user_override_id_list, const std::string& prefix, - const size_t num_ports -) { + const size_t num_ports) +{ const std::vector<std::string> overrides = parse_csv(user_override_id_list); std::deque<noc_block_endpoint> result; for (size_t i = 0; i < num_blocks; i++) { if (i < overrides.size()) { result.push_back({overrides[i], (i % num_ports)}); - } - else { + } else { const std::string format_str = prefix + "_%d"; - noc_block_endpoint block = { - str(boost::format(format_str) % (i/num_ports)), - i % num_ports}; + noc_block_endpoint block = { + str(boost::format(format_str) % (i / num_ports)), i % num_ports}; result.push_back(block); } } return result; } -int UHD_SAFE_MAIN(int argc, char *argv[]) { +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ // Variables to be set by po bool dma_fifo, ddc, duc, tx_loopback_fifo, rx_loopback_fifo; std::string args, format; @@ -656,52 +665,54 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) { if (vm.count("help") or (num_streamers == 0)) { std::cout << boost::format("UHD - Benchmark Streamer") << std::endl; - std::cout << - " Benchmark streamer connects a null sink/source to a streamer and\n" - " measures maximum throughput. You can benchmark the operation of\n" - " multiple streamers concurrently. Each streamer executes in a\n" - " separate thread. The FPGA image on the device must contain a\n" - " null source for each channel in the test.\n" - " Benchmarks of common use-cases:\n" - " Specify --num_tx_streamers=1 to test tx streamer.\n" - " Specify --num_rx_streamers=1 to test rx streamer.\n" - " Specify --num_tx_streamers=1 --num_tx_channels-2 to test tx\n" - " streamer with two channels.\n" - " Specify --num_rx_streamers=1 --num_rx_channels=2 to test rx\n" - " rx streamer with two channels. This requires a split_stream\n" - " RFNOC block.\n" - " Specify --num_rx_streamers=1 --num_tx_streams=1 to test full\n" - " duplex data transfer.\n" - " Specify --num_rx_streamers=2 --num_rx_streams=2 to test full\n" - " duplex data tranfser with two streamers in each direction.\n" - " Benchmarks streamer allows DMA FIFOs, loopback FIFOs, DDCs, and\n" - " DUCs to be added to the data path. Enable these by setting the\n" - " corresponding Boolean option to true. The order of the blocks\n" - " is fixed. If present, the DMA FIFO is connected to the host bus\n" - " interface, followed by the loopback FIFOs, and then DUC on a tx\n" - " stream or a DDC on an rx stream.\n" - " Note: for full duplex tests, if a DMA FIFO is specified, it is\n" - " inserted in the tx data path only.\n" - " Testing multiple rx channels in a single streamer requires a\n" - " split stream RFNOC block with the number of outputs equal to the\n" - " number of channels. Each streamer connects to a single null\n" - " source through the split stream block.\n" - " In order to allow testing of blocks with different compilation\n" - " parameters, such as the block FIFO size, this example provides\n" - " options to override RFNOC block IDs. Block IDs can be specified\n" - " as a comma-delimited list for each type of block. If the block\n" - " type is used in both tx and rx streams, block IDs are assigned\n" - " to tx streams first, followed by rx streams. For example, a test\n" - " with two tx and two rx streams will assign the first two IDs in\n" - " the null_ids list to the tx streams and the next two IDs to the\n" - " rx streams.\n" - << std::endl << desc << std::endl; + std::cout + << " Benchmark streamer connects a null sink/source to a streamer and\n" + " measures maximum throughput. You can benchmark the operation of\n" + " multiple streamers concurrently. Each streamer executes in a\n" + " separate thread. The FPGA image on the device must contain a\n" + " null source for each channel in the test.\n" + " Benchmarks of common use-cases:\n" + " Specify --num_tx_streamers=1 to test tx streamer.\n" + " Specify --num_rx_streamers=1 to test rx streamer.\n" + " Specify --num_tx_streamers=1 --num_tx_channels-2 to test tx\n" + " streamer with two channels.\n" + " Specify --num_rx_streamers=1 --num_rx_channels=2 to test rx\n" + " rx streamer with two channels. This requires a split_stream\n" + " RFNOC block.\n" + " Specify --num_rx_streamers=1 --num_tx_streams=1 to test full\n" + " duplex data transfer.\n" + " Specify --num_rx_streamers=2 --num_rx_streams=2 to test full\n" + " duplex data tranfser with two streamers in each direction.\n" + " Benchmarks streamer allows DMA FIFOs, loopback FIFOs, DDCs, and\n" + " DUCs to be added to the data path. Enable these by setting the\n" + " corresponding Boolean option to true. The order of the blocks\n" + " is fixed. If present, the DMA FIFO is connected to the host bus\n" + " interface, followed by the loopback FIFOs, and then DUC on a tx\n" + " stream or a DDC on an rx stream.\n" + " Note: for full duplex tests, if a DMA FIFO is specified, it is\n" + " inserted in the tx data path only.\n" + " Testing multiple rx channels in a single streamer requires a\n" + " split stream RFNOC block with the number of outputs equal to the\n" + " number of channels. Each streamer connects to a single null\n" + " source through the split stream block.\n" + " In order to allow testing of blocks with different compilation\n" + " parameters, such as the block FIFO size, this example provides\n" + " options to override RFNOC block IDs. Block IDs can be specified\n" + " as a comma-delimited list for each type of block. If the block\n" + " type is used in both tx and rx streams, block IDs are assigned\n" + " to tx streams first, followed by rx streams. For example, a test\n" + " with two tx and two rx streams will assign the first two IDs in\n" + " the null_ids list to the tx streams and the next two IDs to the\n" + " rx streams.\n" + << std::endl + << desc << std::endl; return EXIT_SUCCESS; } uhd::set_thread_priority_safe(); - 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::device3::sptr usrp = uhd::device3::make(args); // For each block type, calculate the number of blocks needed by the test @@ -722,38 +733,37 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) { const size_t num_splitter_blocks = num_rx_channels > 1 ? num_rx_streamers : 0; size_t num_dma_fifo_blocks = 0; - bool tx_dma_fifo = false; - bool rx_dma_fifo = false; + bool tx_dma_fifo = false; + bool rx_dma_fifo = false; if (dma_fifo) { if (total_tx_channels == 0) { num_dma_fifo_blocks = total_rx_channels; - rx_dma_fifo = true; - } - else { + rx_dma_fifo = true; + } else { num_dma_fifo_blocks = total_tx_channels; - tx_dma_fifo = true; + tx_dma_fifo = true; } } // Create block IDs - std::deque<noc_block_endpoint> null_blocks = create_noc_block_queue( - num_null_blocks, null_ids, "0/NullSrcSink", 1); + std::deque<noc_block_endpoint> null_blocks = + create_noc_block_queue(num_null_blocks, null_ids, "0/NullSrcSink", 1); - std::deque<noc_block_endpoint> duc_blocks = create_noc_block_queue( - num_duc_blocks, duc_ids, "0/DUC", 1); + std::deque<noc_block_endpoint> duc_blocks = + create_noc_block_queue(num_duc_blocks, duc_ids, "0/DUC", 1); - std::deque<noc_block_endpoint> ddc_blocks = create_noc_block_queue( - num_ddc_blocks, ddc_ids, "0/DDC", 1); + std::deque<noc_block_endpoint> ddc_blocks = + create_noc_block_queue(num_ddc_blocks, ddc_ids, "0/DDC", 1); - std::deque<noc_block_endpoint> fifo_blocks = create_noc_block_queue( - num_fifo_blocks, fifo_ids, "0/FIFO", 1); + std::deque<noc_block_endpoint> fifo_blocks = + create_noc_block_queue(num_fifo_blocks, fifo_ids, "0/FIFO", 1); - std::deque<noc_block_endpoint> dma_fifo_blocks = create_noc_block_queue( - num_dma_fifo_blocks, "", "0/DmaFIFO", 2); + std::deque<noc_block_endpoint> dma_fifo_blocks = + create_noc_block_queue(num_dma_fifo_blocks, "", "0/DmaFIFO", 2); - std::deque<noc_block_endpoint> splitter_blocks = create_noc_block_queue( - num_splitter_blocks, split_stream_ids, "0/SplitStream", 1); + std::deque<noc_block_endpoint> splitter_blocks = + create_noc_block_queue(num_splitter_blocks, split_stream_ids, "0/SplitStream", 1); // Configure all streamers usrp->clear(); @@ -787,8 +797,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) { } }; - tx_streamers.push_back( - configure_tx_streamer(usrp, blocks, spp, format)); + tx_streamers.push_back(configure_tx_streamer(usrp, blocks, spp, format)); tx_null_ids.push_back(null_ids); } @@ -821,14 +830,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) { splitter_blocks.pop_front(); } - rx_streamers.push_back( - configure_rx_streamer( - usrp, - null_blocks.front().block_id, - splitter_id, - blocks, - spp, - format)); + rx_streamers.push_back(configure_rx_streamer( + usrp, null_blocks.front().block_id, splitter_id, blocks, spp, format)); // Store the null ids to read traffic counters later rx_null_ids.push_back(null_blocks.front().block_id); @@ -839,38 +842,26 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) { std::vector<std::thread> threads; std::vector<test_results> tx_results(num_tx_streamers); for (size_t i = 0; i < num_tx_streamers; i++) { - test_results& results = tx_results[i]; - uhd::tx_streamer::sptr streamer = tx_streamers[i]; + test_results& results = tx_results[i]; + uhd::tx_streamer::sptr streamer = tx_streamers[i]; std::vector<std::string> null_ids = tx_null_ids[i]; threads.push_back( - std::thread( - [&results, usrp, streamer, null_ids, duration, format]() { - results = benchmark_tx_streamer( - usrp, - streamer, - null_ids, - duration, - format); - }) - ); + std::thread([&results, usrp, streamer, null_ids, duration, format]() { + results = + benchmark_tx_streamer(usrp, streamer, null_ids, duration, format); + })); } std::vector<test_results> rx_results(num_rx_streamers); for (size_t i = 0; i < num_rx_streamers; i++) { - test_results& results = rx_results[i]; + test_results& results = rx_results[i]; uhd::rx_streamer::sptr streamer = rx_streamers[i]; - std::string null_id = rx_null_ids[i]; + std::string null_id = rx_null_ids[i]; threads.push_back( - std::thread( - [&results, usrp, streamer, null_id, duration, format]() { - results = benchmark_rx_streamer( - usrp, - streamer, - null_id, - duration, - format); - }) - ); + std::thread([&results, usrp, streamer, null_id, duration, format]() { + results = + benchmark_rx_streamer(usrp, streamer, null_id, duration, format); + })); } // Join threads @@ -879,11 +870,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) { } // Print results - for (const test_results& result: tx_results) { + for (const test_results& result : tx_results) { print_tx_results(result, bus_clk_freq); } - for (const test_results& result: rx_results) { + for (const test_results& result : rx_results) { print_rx_results(result, bus_clk_freq); } diff --git a/host/examples/gpio.cpp b/host/examples/gpio.cpp index 537da80ca..0ed8d01ef 100644 --- a/host/examples/gpio.cpp +++ b/host/examples/gpio.cpp @@ -63,29 +63,29 @@ // mask - a mask indicating which bits in the specified attribute register are // to be changed (default is all bits). -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/multi_usrp.hpp> #include <uhd/convert.hpp> -#include <boost/program_options.hpp> +#include <uhd/usrp/multi_usrp.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> +#include <stdint.h> +#include <stdlib.h> #include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <chrono> #include <csignal> #include <iostream> #include <thread> -#include <chrono> -#include <stdlib.h> -#include <stdint.h> -static const std::string GPIO_DEFAULT_CPU_FORMAT = "fc32"; -static const std::string GPIO_DEFAULT_OTW_FORMAT = "sc16"; -static const double GPIO_DEFAULT_RX_RATE = 500e3; -static const double GPIO_DEFAULT_TX_RATE = 500e3; -static const double GPIO_DEFAULT_DWELL_TIME = 2.0; -static const std::string GPIO_DEFAULT_GPIO = "FP0"; -static const size_t GPIO_DEFAULT_NUM_BITS = 11; -static const std::string GPIO_DEFAULT_CTRL = "0x0"; // all as user controlled -static const std::string GPIO_DEFAULT_DDR = "0x0"; // all as inputs -static const std::string GPIO_DEFAULT_OUT = "0x0"; +static const std::string GPIO_DEFAULT_CPU_FORMAT = "fc32"; +static const std::string GPIO_DEFAULT_OTW_FORMAT = "sc16"; +static const double GPIO_DEFAULT_RX_RATE = 500e3; +static const double GPIO_DEFAULT_TX_RATE = 500e3; +static const double GPIO_DEFAULT_DWELL_TIME = 2.0; +static const std::string GPIO_DEFAULT_GPIO = "FP0"; +static const size_t GPIO_DEFAULT_NUM_BITS = 11; +static const std::string GPIO_DEFAULT_CTRL = "0x0"; // all as user controlled +static const std::string GPIO_DEFAULT_DDR = "0x0"; // all as inputs +static const std::string GPIO_DEFAULT_OUT = "0x0"; static inline uint32_t GPIO_BIT(const size_t x) { @@ -95,13 +95,15 @@ static inline uint32_t GPIO_BIT(const size_t x) namespace po = boost::program_options; static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} std::string to_bit_string(uint32_t val, const size_t num_bits) { std::string out; - for (int i = num_bits - 1; i >= 0; i--) - { + for (int i = num_bits - 1; i >= 0; i--) { std::string bit = ((val >> i) & 1) ? "1" : "0"; out += " "; out += bit; @@ -109,39 +111,29 @@ std::string to_bit_string(uint32_t val, const size_t num_bits) return out; } -void output_reg_values( - const std::string bank, - const uhd::usrp::multi_usrp::sptr &usrp, - const size_t num_bits -) { +void output_reg_values(const std::string bank, + const uhd::usrp::multi_usrp::sptr& usrp, + const size_t num_bits) +{ const std::vector<std::string> attrs = { - "CTRL", - "DDR", - "ATR_0X", - "ATR_RX", - "ATR_TX", - "ATR_XX", - "OUT", - "READBACK" - }; + "CTRL", "DDR", "ATR_0X", "ATR_RX", "ATR_TX", "ATR_XX", "OUT", "READBACK"}; std::cout << (boost::format("%10s ") % "Bit"); for (int i = num_bits - 1; i >= 0; i--) std::cout << (boost::format(" %2d") % i); std::cout << std::endl; - for (const auto &attr : attrs) { + for (const auto& attr : attrs) { const uint32_t gpio_bits = uint32_t(usrp->get_gpio_attr(bank, attr)); - std::cout - << (boost::format("%10s:%s") - % attr % to_bit_string(gpio_bits, num_bits)) - << std::endl; + std::cout << (boost::format("%10s:%s") % attr + % to_bit_string(gpio_bits, num_bits)) + << std::endl; } } -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; std::string cpu, otw; double rx_rate, tx_rate, dwell; @@ -151,7 +143,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::string ddr_str; std::string out_str; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -174,80 +166,80 @@ 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("gpio %s") % desc << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //print out initial unconfigured state of FP GPIO + // print out initial unconfigured state of FP GPIO std::cout << "Initial GPIO values:" << std::endl; output_reg_values(gpio, usrp, num_bits); - //configure GPIO registers - uint32_t ddr = strtoul(ddr_str.c_str(), NULL, 0); - uint32_t out = strtoul(out_str.c_str(), NULL, 0); - uint32_t ctrl = 0; - uint32_t atr_idle = 0; - uint32_t atr_rx = 0; - uint32_t atr_tx = 0; + // configure GPIO registers + uint32_t ddr = strtoul(ddr_str.c_str(), NULL, 0); + uint32_t out = strtoul(out_str.c_str(), NULL, 0); + uint32_t ctrl = 0; + uint32_t atr_idle = 0; + uint32_t atr_rx = 0; + uint32_t atr_tx = 0; uint32_t atr_duplex = 0; - uint32_t mask = (1 << num_bits) - 1; + uint32_t mask = (1 << num_bits) - 1; - if (!vm.count("bitbang")) - { - //set up GPIO outputs: - //GPIO[0] = ATR output 1 at idle + if (!vm.count("bitbang")) { + // set up GPIO outputs: + // GPIO[0] = ATR output 1 at idle ctrl |= GPIO_BIT(0); atr_idle |= GPIO_BIT(0); ddr |= GPIO_BIT(0); - //GPIO[1] = ATR output 1 during RX + // GPIO[1] = ATR output 1 during RX ctrl |= GPIO_BIT(1); ddr |= GPIO_BIT(1); atr_rx |= GPIO_BIT(1); - //GPIO[2] = ATR output 1 during TX + // GPIO[2] = ATR output 1 during TX ctrl |= GPIO_BIT(2); ddr |= GPIO_BIT(2); atr_tx |= GPIO_BIT(2); - //GPIO[3] = ATR output 1 during full duplex + // GPIO[3] = ATR output 1 during full duplex ctrl |= GPIO_BIT(3); ddr |= GPIO_BIT(3); atr_duplex |= GPIO_BIT(3); - //GPIO[4] = output + // GPIO[4] = output ddr |= GPIO_BIT(4); } - //set data direction register (DDR) + // set data direction register (DDR) usrp->set_gpio_attr(gpio, "DDR", ddr, mask); - //set control register + // set control register usrp->set_gpio_attr(gpio, "CTRL", ctrl, mask); - //set output values (OUT) + // set output values (OUT) usrp->set_gpio_attr(gpio, "OUT", out, mask); - //set ATR registers + // set ATR registers usrp->set_gpio_attr(gpio, "ATR_0X", atr_idle, mask); usrp->set_gpio_attr(gpio, "ATR_RX", atr_rx, mask); usrp->set_gpio_attr(gpio, "ATR_TX", atr_tx, mask); usrp->set_gpio_attr(gpio, "ATR_XX", atr_duplex, mask); - //print out initial state of FP GPIO + // print out initial state of FP GPIO std::cout << "\nConfigured GPIO values:" << std::endl; output_reg_values(gpio, usrp, num_bits); std::cout << std::endl; - //set up streams + // set up streams uhd::stream_args_t rx_args(cpu, otw); uhd::stream_args_t tx_args(cpu, otw); uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(rx_args); @@ -257,20 +249,22 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) usrp->set_rx_rate(rx_rate); usrp->set_tx_rate(tx_rate); - //set up buffers for tx and rx + // set up buffers for tx and rx const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); - const size_t nsamps_per_buff = max_samps_per_packet; - std::vector<char> rx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); - std::vector<char> tx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); - std::vector<void *> rx_buffs, tx_buffs; + const size_t nsamps_per_buff = max_samps_per_packet; + std::vector<char> rx_buff( + max_samps_per_packet * uhd::convert::get_bytes_per_item(cpu)); + std::vector<char> tx_buff( + max_samps_per_packet * uhd::convert::get_bytes_per_item(cpu)); + std::vector<void*> rx_buffs, tx_buffs; for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) - rx_buffs.push_back(&rx_buff.front()); //same buffer for each channel + rx_buffs.push_back(&rx_buff.front()); // same buffer for each channel for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) - tx_buffs.push_back(&tx_buff.front()); //same buffer for each channel + tx_buffs.push_back(&tx_buff.front()); // same buffer for each channel uhd::rx_metadata_t rx_md; uhd::tx_metadata_t tx_md; - tx_md.has_time_spec = false; + tx_md.has_time_spec = false; tx_md.start_of_burst = true; uhd::time_spec_t stop_time; double timeout = 0.01; @@ -278,61 +272,54 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) int loop = 0; uint32_t rb, expected; - //register signal handler + // register signal handler std::signal(SIGINT, &sig_int_handler); - if (!vm.count("bitbang")) - { + if (!vm.count("bitbang")) { // Test the mask parameter of the multi_usrp::set_gpio_attr API // We only need to test once with no dwell time std::cout << "\nTesting mask..." << std::flush; - //send a value of all 1's to the DDR with a mask for only upper most bit + // send a value of all 1's to the DDR with a mask for only upper most bit usrp->set_gpio_attr(gpio, "DDR", ~0, GPIO_BIT(num_bits - 1)); - //upper most bit should now be 1, but all the other bits should be unchanged - rb = usrp->get_gpio_attr(gpio, "DDR") & mask; + // upper most bit should now be 1, but all the other bits should be unchanged + rb = usrp->get_gpio_attr(gpio, "DDR") & mask; expected = ddr | GPIO_BIT(num_bits - 1); if (rb == expected) std::cout << "pass:" << std::endl; else std::cout << "fail:" << std::endl; output_reg_values(gpio, usrp, num_bits); - //restore DDR value + // restore DDR value usrp->set_gpio_attr(gpio, "DDR", ddr, mask); } - while (not stop_signal_called) - { + while (not stop_signal_called) { int failures = 0; if (vm.count("repeat")) std::cout << "Press Ctrl + C to quit..." << std::endl; - if (vm.count("bitbang")) - { + if (vm.count("bitbang")) { // dwell and continuously read back GPIO values stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { + while (not stop_signal_called and usrp->get_time_now() < stop_time) { rb = usrp->get_gpio_attr(gpio, "READBACK"); std::cout << "\rREADBACK: " << to_bit_string(rb, num_bits); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } std::cout << std::endl; - } - else - { + } else { // test user controlled GPIO and ATR idle by setting bit 4 high for 1 second - std::cout << "\nTesting user controlled GPIO and ATR idle output..." << std::flush; + std::cout << "\nTesting user controlled GPIO and ATR idle output..." + << std::flush; usrp->set_gpio_attr(gpio, "OUT", 1 << 4, 1 << 4); stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { + while (not stop_signal_called and usrp->get_time_now() < stop_time) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - rb = usrp->get_gpio_attr(gpio, "READBACK"); + rb = usrp->get_gpio_attr(gpio, "READBACK"); expected = GPIO_BIT(4) | GPIO_BIT(0); - if ((rb & expected) != expected) - { + if ((rb & expected) != expected) { ++failures; std::cout << "fail:" << std::endl; if ((rb & GPIO_BIT(0)) == 0) @@ -352,16 +339,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; rx_stream->issue_stream_cmd(rx_cmd); stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { + while (not stop_signal_called and usrp->get_time_now() < stop_time) { try { rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} + } catch (...) { + } } - rb = usrp->get_gpio_attr(gpio, "READBACK"); + rb = usrp->get_gpio_attr(gpio, "READBACK"); expected = GPIO_BIT(1); - if ((rb & expected) != expected) - { + if ((rb & expected) != expected) { ++failures; std::cout << "fail:" << std::endl; std::cout << "Bit 1 should be set, but is not" << std::endl; @@ -370,29 +356,29 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } output_reg_values(gpio, usrp, num_bits); rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - //clear out any data left in the rx stream + // clear out any data left in the rx stream try { rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} + } catch (...) { + } if (stop_signal_called) break; // test ATR TX by transmitting for 1 second std::cout << "\nTesting ATR TX output..." << std::flush; - stop_time = usrp->get_time_now() + dwell_time; + stop_time = usrp->get_time_now() + dwell_time; tx_md.start_of_burst = true; - tx_md.end_of_burst = false; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { + tx_md.end_of_burst = false; + while (not stop_signal_called and usrp->get_time_now() < stop_time) { try { tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); tx_md.start_of_burst = false; - } catch(...){} + } catch (...) { + } } - rb = usrp->get_gpio_attr(gpio, "READBACK"); + rb = usrp->get_gpio_attr(gpio, "READBACK"); expected = GPIO_BIT(2); - if ((rb & expected) != expected) - { + if ((rb & expected) != expected) { ++failures; std::cout << "fail:" << std::endl; std::cout << "Bit 2 should be set, but is not" << std::endl; @@ -403,7 +389,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) tx_md.end_of_burst = true; try { tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); - } catch(...){} + } catch (...) { + } if (stop_signal_called) break; @@ -412,20 +399,19 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; rx_stream->issue_stream_cmd(rx_cmd); tx_md.start_of_burst = true; - tx_md.end_of_burst = false; - stop_time = usrp->get_time_now() + dwell_time; - while (not stop_signal_called and usrp->get_time_now() < stop_time) - { + tx_md.end_of_burst = false; + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) { try { tx_stream->send(rx_buffs, nsamps_per_buff, tx_md, timeout); tx_md.start_of_burst = false; rx_stream->recv(tx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} + } catch (...) { + } } - rb = usrp->get_gpio_attr(gpio, "READBACK"); + rb = usrp->get_gpio_attr(gpio, "READBACK"); expected = GPIO_BIT(3); - if ((rb & expected) != expected) - { + if ((rb & expected) != expected) { ++failures; std::cout << "fail:" << std::endl; std::cout << "Bit 3 should be set, but is not" << std::endl; @@ -437,11 +423,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) tx_md.end_of_burst = true; try { tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); - } catch(...){} - //clear out any data left in the rx stream + } catch (...) { + } + // clear out any data left in the rx stream try { rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); - } catch(...){} + } catch (...) { + } std::cout << std::endl; if (failures) @@ -454,10 +442,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) break; if (not stop_signal_called) - std::cout << (boost::format("\nLoop %d completed") % ++loop) << std::endl; + std::cout << (boost::format("\nLoop %d completed") % ++loop) << std::endl; } - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/init_usrp/init_usrp.cpp b/host/examples/init_usrp/init_usrp.cpp index 302db355b..62515b538 100644 --- a/host/examples/init_usrp/init_usrp.cpp +++ b/host/examples/init_usrp/init_usrp.cpp @@ -10,40 +10,42 @@ // The program itself only initializes a USRP. For more elaborate examples, // have a look at the files in host/examples/. -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args") - ; + desc.add_options()("help", "help message")("args", + po::value<std::string>(&args)->default_value(""), + "multi uhd device address args"); 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("Mini-example to initialize a USRP (args==%s).") % args << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("Mini-example to initialize a USRP (args==%s).") % args + << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); return EXIT_SUCCESS; diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp index 9a173b8a4..798279310 100644 --- a/host/examples/latency_test.cpp +++ b/host/examples/latency_test.cpp @@ -5,27 +5,28 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> +#include <boost/program_options.hpp> #include <complex> +#include <iostream> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; size_t nsamps; double rate; double rtt; size_t nruns; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -42,90 +43,82 @@ 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 - Latency Test %s") % desc << std::endl; - std::cout << - " Latency test receives a packet at time t,\n" - " and tries to send a packet at time t + rtt,\n" - " where rtt is the round trip time sample time\n" - " from device to host and back to the device.\n" - " This can be used to test latency between UHD and the device.\n" - " If the value rtt is chosen too small, the transmit packet will.\n" - " arrive too late at the device indicate an error.\n" - " The smallest value of rtt that does not indicate an error is an\n" - " approximation for the time it takes for a sample packet to\n" - " go to UHD and back to the device." - << std::endl; + std::cout + << " Latency test receives a packet at time t,\n" + " and tries to send a packet at time t + rtt,\n" + " where rtt is the round trip time sample time\n" + " from device to host and back to the device.\n" + " This can be used to test latency between UHD and the device.\n" + " If the value rtt is chosen too small, the transmit packet will.\n" + " arrive too late at the device indicate an error.\n" + " The smallest value of rtt that does not indicate an error is an\n" + " approximation for the time it takes for a sample packet to\n" + " go to UHD and back to the device." + << std::endl; return EXIT_SUCCESS; } bool verbose = vm.count("verbose") != 0; - //create a usrp device + // create a usrp device 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); - //std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; + // std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << + // std::endl; usrp->set_time_now(uhd::time_spec_t(0.0)); - //set the tx sample rate + // set the tx sample rate usrp->set_tx_rate(rate); - std::cout - << boost::format("Actual TX Rate: %f Msps...") - % (usrp->get_tx_rate()/1e6) - << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6) + << std::endl; - //set the rx sample rate + // set the rx sample rate usrp->set_rx_rate(rate); - std::cout - << boost::format("Actual RX Rate: %f Msps...") - % (usrp->get_rx_rate()/1e6) - << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate() / 1e6) + << std::endl; - //allocate a buffer to use - std::vector<std::complex<float> > buffer(nsamps); + // allocate a buffer to use + std::vector<std::complex<float>> buffer(nsamps); - //create RX and TX streamers - uhd::stream_args_t stream_args("fc32"); //complex floats + // create RX and TX streamers + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //initialize result counts + // initialize result counts int time_error = 0; - int ack = 0; - int underflow = 0; - int other = 0; - - for(size_t nrun = 0; nrun < nruns; nrun++){ + int ack = 0; + int underflow = 0; + int other = 0; + for (size_t nrun = 0; nrun < nruns; nrun++) { /*************************************************************** * Issue a stream command some time in the near future **************************************************************/ uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = buffer.size(); + stream_cmd.num_samps = buffer.size(); stream_cmd.stream_now = false; - stream_cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.01); + stream_cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.01); rx_stream->issue_stream_cmd(stream_cmd); /*************************************************************** * Receive the requested packet **************************************************************/ uhd::rx_metadata_t rx_md; - size_t num_rx_samps = rx_stream->recv( - &buffer.front(), buffer.size(), rx_md - ); + size_t num_rx_samps = rx_stream->recv(&buffer.front(), buffer.size(), rx_md); if (verbose) { std::cout << boost::format( - "Run %d: Got packet: %u samples, %u full secs, %f frac secs" - ) - % nrun - % num_rx_samps - % rx_md.time_spec.get_full_secs() - % rx_md.time_spec.get_frac_secs() - << std::endl; + "Run %d: Got packet: %u samples, %u full secs, %f frac secs") + % nrun % num_rx_samps % rx_md.time_spec.get_full_secs() + % rx_md.time_spec.get_frac_secs() + << std::endl; } else { std::cout << "." << std::flush; } @@ -135,45 +128,43 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ **************************************************************/ uhd::tx_metadata_t tx_md; tx_md.start_of_burst = true; - tx_md.end_of_burst = true; - tx_md.has_time_spec = true; - tx_md.time_spec = rx_md.time_spec + uhd::time_spec_t(rtt); - size_t num_tx_samps = tx_stream->send( - &buffer.front(), buffer.size(), tx_md - ); + tx_md.end_of_burst = true; + tx_md.has_time_spec = true; + tx_md.time_spec = rx_md.time_spec + uhd::time_spec_t(rtt); + size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), tx_md); if (verbose) { - std::cout - << boost::format("Sent %d samples") % num_tx_samps - << std::endl; + std::cout << boost::format("Sent %d samples") % num_tx_samps << std::endl; } /*************************************************************** * Check the async messages for result **************************************************************/ uhd::async_metadata_t async_md; - if (not tx_stream->recv_async_msg(async_md)){ - std::cout << boost::format("failed:\n Async message recv timed out.\n") << std::endl; + if (not tx_stream->recv_async_msg(async_md)) { + std::cout << boost::format("failed:\n Async message recv timed out.\n") + << std::endl; continue; } - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: - time_error++; - break; - - case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: - ack++; - break; - - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: - underflow++; - break; - - default: - std::cerr << boost::format( - "failed:\n Got unexpected event code 0x%x.\n" - ) % async_md.event_code << std::endl; - other++; - break; + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: + time_error++; + break; + + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + ack++; + break; + + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + underflow++; + break; + + default: + std::cerr << boost::format( + "failed:\n Got unexpected event code 0x%x.\n") + % async_md.event_code + << std::endl; + other++; + break; } } @@ -182,25 +173,26 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ if (not tx_stream->recv_async_msg(async_md)) { break; } - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: - time_error++; - break; - - case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: - ack++; - break; - - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: - underflow++; - break; - - default: - std::cerr << boost::format( - "failed:\n Got unexpected event code 0x%x.\n" - ) % async_md.event_code << std::endl; - other++; - break; + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: + time_error++; + break; + + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + ack++; + break; + + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + underflow++; + break; + + default: + std::cerr << boost::format( + "failed:\n Got unexpected event code 0x%x.\n") + % async_md.event_code + << std::endl; + other++; + break; } } if (!verbose) { @@ -213,7 +205,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "Summary\n" << "================\n" << "Number of runs: " << nruns << std::endl - << "RTT value tested: " << (rtt*1e3) << " ms" << std::endl + << "RTT value tested: " << (rtt * 1e3) << " ms" << std::endl << "ACKs received: " << ack << "/" << nruns << std::endl << "Underruns: " << underflow << std::endl << "Late packets: " << time_error << std::endl diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp index 3f4a1d711..464d2084d 100644 --- a/host/examples/network_relay.cpp +++ b/host/examples/network_relay.cpp @@ -5,21 +5,21 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> #include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/asio.hpp> +#include <boost/format.hpp> #include <boost/program_options.hpp> #include <boost/thread/condition_variable.hpp> #include <boost/thread/thread.hpp> -#include <boost/format.hpp> -#include <boost/asio.hpp> -#include <iostream> +#include <chrono> #include <csignal> -#include <vector> #include <cstdlib> -#include <chrono> +#include <iostream> #include <thread> +#include <vector> -namespace po = boost::program_options; +namespace po = boost::program_options; namespace asio = boost::asio; typedef boost::shared_ptr<asio::ip::udp::socket> socket_type; @@ -27,11 +27,11 @@ typedef boost::shared_ptr<asio::ip::udp::socket> socket_type; static const size_t insane_mtu = 9000; #if defined(UHD_PLATFORM_MACOS) - //limit buffer resize on macos or it will error - const size_t rx_dsp_buff_size = size_t(1e6); +// limit buffer resize on macos or it will error +const size_t rx_dsp_buff_size = size_t(1e6); #else - //set to half-a-second of buffering at max rate - const size_t rx_dsp_buff_size = size_t(50e6); +// set to half-a-second of buffering at max rate +const size_t rx_dsp_buff_size = size_t(50e6); #endif const size_t tx_dsp_buff_size = (1 << 20); @@ -40,43 +40,49 @@ const size_t tx_dsp_buff_size = (1 << 20); * Signal handlers **********************************************************************/ static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} -static bool wait_for_recv_ready(int sock_fd){ - //setup timeval for timeout +static bool wait_for_recv_ready(int sock_fd) +{ + // setup timeval for timeout timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 100000; //100ms + tv.tv_sec = 0; + tv.tv_usec = 100000; // 100ms - //setup rset for timeout + // setup rset for timeout fd_set rset; FD_ZERO(&rset); FD_SET(sock_fd, &rset); - //call select with timeout on receive socket - return ::select(sock_fd+1, &rset, NULL, NULL, &tv) > 0; + // call select with timeout on receive socket + return ::select(sock_fd + 1, &rset, NULL, NULL, &tv) > 0; } /*********************************************************************** * Relay class **********************************************************************/ -class udp_relay_type{ +class udp_relay_type +{ public: - udp_relay_type( - const std::string &server_addr, - const std::string &client_addr, - const std::string &port, + udp_relay_type(const std::string& server_addr, + const std::string& client_addr, + const std::string& port, const size_t server_rx_size = 0, const size_t server_tx_size = 0, const size_t client_rx_size = 0, - const size_t client_tx_size = 0 - ):_port(port){ + const size_t client_tx_size = 0) + : _port(port) + { { asio::ip::udp::resolver resolver(_io_service); asio::ip::udp::resolver::query query(asio::ip::udp::v4(), server_addr, port); asio::ip::udp::endpoint endpoint = *resolver.resolve(query); - _server_socket = boost::shared_ptr<asio::ip::udp::socket>(new asio::ip::udp::socket(_io_service, endpoint)); + _server_socket = boost::shared_ptr<asio::ip::udp::socket>( + new asio::ip::udp::socket(_io_service, endpoint)); resize_buffs(_server_socket, server_rx_size, server_tx_size); } { @@ -84,22 +90,27 @@ public: asio::ip::udp::resolver::query query(asio::ip::udp::v4(), client_addr, port); asio::ip::udp::endpoint endpoint = *resolver.resolve(query); - _client_socket = boost::shared_ptr<asio::ip::udp::socket>(new asio::ip::udp::socket(_io_service)); + _client_socket = boost::shared_ptr<asio::ip::udp::socket>( + new asio::ip::udp::socket(_io_service)); _client_socket->open(asio::ip::udp::v4()); _client_socket->connect(endpoint); resize_buffs(_client_socket, client_rx_size, client_tx_size); } std::cout << "spawning relay threads... " << _port << std::endl; - boost::unique_lock<boost::mutex> lock(spawn_mutex); // lock in preparation to wait for threads to spawn - (void)_thread_group.create_thread(boost::bind(&udp_relay_type::server_thread, this)); - wait_for_thread.wait(lock); // wait for thread to spin up - (void)_thread_group.create_thread(boost::bind(&udp_relay_type::client_thread, this)); - wait_for_thread.wait(lock); // wait for thread to spin up + boost::unique_lock<boost::mutex> lock( + spawn_mutex); // lock in preparation to wait for threads to spawn + (void)_thread_group.create_thread( + boost::bind(&udp_relay_type::server_thread, this)); + wait_for_thread.wait(lock); // wait for thread to spin up + (void)_thread_group.create_thread( + boost::bind(&udp_relay_type::client_thread, this)); + wait_for_thread.wait(lock); // wait for thread to spin up std::cout << " done!" << std::endl << std::endl; } - ~udp_relay_type(void){ + ~udp_relay_type(void) + { std::cout << "killing relay threads... " << _port << std::endl; _thread_group.interrupt_all(); _thread_group.join_all(); @@ -107,31 +118,36 @@ public: } private: - - static void resize_buffs(socket_type sock, const size_t rx_size, const size_t tx_size){ - if (rx_size != 0) sock->set_option(asio::socket_base::receive_buffer_size(rx_size)); - if (tx_size != 0) sock->set_option(asio::socket_base::send_buffer_size(tx_size)); + static void resize_buffs(socket_type sock, const size_t rx_size, const size_t tx_size) + { + if (rx_size != 0) + sock->set_option(asio::socket_base::receive_buffer_size(rx_size)); + if (tx_size != 0) + sock->set_option(asio::socket_base::send_buffer_size(tx_size)); } - void server_thread(void){ + void server_thread(void) + { uhd::set_thread_priority_safe(); std::cout << " entering server_thread..." << std::endl; - wait_for_thread.notify_one(); // notify constructor that this thread has started + wait_for_thread.notify_one(); // notify constructor that this thread has started std::vector<char> buff(insane_mtu); - while (not boost::this_thread::interruption_requested()){ - if (wait_for_recv_ready(_server_socket->native_handle())){ + while (not boost::this_thread::interruption_requested()) { + if (wait_for_recv_ready(_server_socket->native_handle())) { boost::mutex::scoped_lock lock(_endpoint_mutex); - const size_t len = _server_socket->receive_from(asio::buffer(&buff.front(), buff.size()), _endpoint); + const size_t len = _server_socket->receive_from( + asio::buffer(&buff.front(), buff.size()), _endpoint); lock.unlock(); _client_socket->send(asio::buffer(&buff.front(), len)); - //perform sequence error detection on tx dsp data (can detect bad network cards) + // perform sequence error detection on tx dsp data (can detect bad network + // cards) /* if (_port[4] == '7'){ static uint32_t next_seq; - const uint32_t this_seq = ntohl(reinterpret_cast<const uint32_t *>(&buff.front())[0]); - if (next_seq != this_seq and this_seq != 0) std::cout << "S" << std::flush; - next_seq = this_seq + 1; + const uint32_t this_seq = ntohl(reinterpret_cast<const uint32_t + *>(&buff.front())[0]); if (next_seq != this_seq and this_seq != 0) + std::cout << "S" << std::flush; next_seq = this_seq + 1; } */ } @@ -139,14 +155,16 @@ private: std::cout << " exiting server_thread..." << std::endl; } - void client_thread(void){ + void client_thread(void) + { uhd::set_thread_priority_safe(); std::cout << " entering client_thread..." << std::endl; - wait_for_thread.notify_one(); // notify constructor that this thread has started + wait_for_thread.notify_one(); // notify constructor that this thread has started std::vector<char> buff(insane_mtu); - while (not boost::this_thread::interruption_requested()){ - if (wait_for_recv_ready(_client_socket->native_handle())){ - const size_t len = _client_socket->receive(asio::buffer(&buff.front(), buff.size())); + while (not boost::this_thread::interruption_requested()) { + if (wait_for_recv_ready(_client_socket->native_handle())) { + const size_t len = + _client_socket->receive(asio::buffer(&buff.front(), buff.size())); boost::mutex::scoped_lock lock(_endpoint_mutex); _server_socket->send_to(asio::buffer(&buff.front(), len), _endpoint); } @@ -168,14 +186,15 @@ private: /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string addr; std::string bind; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -188,32 +207,36 @@ 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("addr")){ - std::cout - << boost::format("UHD Network Relay %s") % desc << std::endl - << "Runs a network relay between UHD on one computer and a USRP on the network.\n" - << "This example is basically for test purposes. Use at your own convenience.\n" - << std::endl; + // print the help message + if (vm.count("help") or not vm.count("addr")) { + std::cout << boost::format("UHD Network Relay %s") % desc << std::endl + << "Runs a network relay between UHD on one computer and a USRP on the " + "network.\n" + << "This example is basically for test purposes. Use at your own " + "convenience.\n" + << std::endl; return EXIT_FAILURE; } { - boost::shared_ptr<udp_relay_type> ctrl (new udp_relay_type(bind, addr, "49152")); - boost::shared_ptr<udp_relay_type> rxdsp0(new udp_relay_type(bind, addr, "49156", 0, tx_dsp_buff_size, rx_dsp_buff_size, 0)); - boost::shared_ptr<udp_relay_type> txdsp0(new udp_relay_type(bind, addr, "49157", tx_dsp_buff_size, 0, 0, tx_dsp_buff_size)); - boost::shared_ptr<udp_relay_type> rxdsp1(new udp_relay_type(bind, addr, "49158", 0, tx_dsp_buff_size, rx_dsp_buff_size, 0)); - boost::shared_ptr<udp_relay_type> gps (new udp_relay_type(bind, addr, "49172")); + boost::shared_ptr<udp_relay_type> ctrl(new udp_relay_type(bind, addr, "49152")); + boost::shared_ptr<udp_relay_type> rxdsp0(new udp_relay_type( + bind, addr, "49156", 0, tx_dsp_buff_size, rx_dsp_buff_size, 0)); + boost::shared_ptr<udp_relay_type> txdsp0(new udp_relay_type( + bind, addr, "49157", tx_dsp_buff_size, 0, 0, tx_dsp_buff_size)); + boost::shared_ptr<udp_relay_type> rxdsp1(new udp_relay_type( + bind, addr, "49158", 0, tx_dsp_buff_size, rx_dsp_buff_size, 0)); + boost::shared_ptr<udp_relay_type> gps(new udp_relay_type(bind, addr, "49172")); std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; - while (not stop_signal_called){ + while (not stop_signal_called) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/replay_samples_from_file.cpp b/host/examples/replay_samples_from_file.cpp index 07691df2b..8f022b4f2 100644 --- a/host/examples/replay_samples_from_file.cpp +++ b/host/examples/replay_samples_from_file.cpp @@ -10,25 +10,23 @@ // It streams the file data to the Replay block, where it is recorded, then it // is played back to the radio. -#include <uhd/utils/safe_main.hpp> #include <uhd/device3.hpp> #include <uhd/rfnoc/radio_ctrl.hpp> #include <uhd/rfnoc/replay_block_ctrl.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/format.hpp> -#include <fstream> +#include <boost/program_options.hpp> #include <csignal> +#include <fstream> #include <thread> - namespace po = boost::program_options; using std::cout; using std::endl; - /////////////////////////////////////////////////////////////////////////////// static volatile bool stop_signal_called = false; @@ -40,8 +38,7 @@ void sig_int_handler(int) } - -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { // We use sc16 in this example, but the replay block only uses 64-bit words // and is not aware of the CPU or wire format. @@ -49,10 +46,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::string cpu_format("sc16"); // Constants related to the Replay block - const size_t replay_word_size = 8; // Size of words used by replay block - const size_t bytes_per_sample = 4; // Complex signed 16-bit is 32 bits per sample - const size_t samples_per_word = 2; // Number of sc16 samples per word - const size_t replay_spp = 2000; // SC16 Samples per packet generated by Replay block + const size_t replay_word_size = 8; // Size of words used by replay block + const size_t bytes_per_sample = 4; // Complex signed 16-bit is 32 bits per sample + const size_t samples_per_word = 2; // Number of sc16 samples per word + const size_t replay_spp = 2000; // SC16 Samples per packet generated by Replay block /////////////////////////////////////////////////////////////////////////// @@ -89,9 +86,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Print help message if (vm.count("help")) { cout << boost::format("UHD/RFNoC Replay samples from file %s") % desc << endl; - cout - << "This application uses the Replay block to playback data from a file to a radio" << endl - << endl; + cout << "This application uses the Replay block to playback data from a file to " + "a radio" + << endl + << endl; return EXIT_FAILURE; } @@ -117,7 +115,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) return EXIT_FAILURE; } replay_ctrl = usrp->get_block_ctrl<uhd::rfnoc::replay_block_ctrl>(replay_ctrl_id); - std::cout << "Using replay block " << replay_id << ", channel " << replay_chan << std::endl; + std::cout << "Using replay block " << replay_id << ", channel " << replay_chan + << std::endl; /////////////////////////////////////////////////////////////////////////// @@ -130,37 +129,47 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) radio_ctrl->set_args(radio_args); // Set the center frequency - if (not vm.count("freq")){ + if (not vm.count("freq")) { std::cerr << "Please specify the center frequency with --freq" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; + std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq / 1e6) << std::endl; radio_ctrl->set_tx_frequency(freq, radio_chan); - std::cout << boost::format("Actual TX Freq: %f MHz...") % (radio_ctrl->get_tx_frequency(radio_chan)/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Freq: %f MHz...") + % (radio_ctrl->get_tx_frequency(radio_chan) / 1e6) + << std::endl + << std::endl; // Set the sample rate if (vm.count("rate")) { - std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) + << std::endl; radio_ctrl->set_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (radio_ctrl->get_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") + % (radio_ctrl->get_rate() / 1e6) + << std::endl + << std::endl; } // Set the RF gain - if (vm.count("gain")){ + if (vm.count("gain")) { std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl; radio_ctrl->set_tx_gain(gain, radio_chan); - std::cout << boost::format("Actual TX Gain: %f dB...") % radio_ctrl->get_tx_gain(radio_chan) << std::endl << std::endl; + std::cout << boost::format("Actual TX Gain: %f dB...") + % radio_ctrl->get_tx_gain(radio_chan) + << std::endl + << std::endl; } // Set the analog front-end filter bandwidth - if (vm.count("bw")){ - std::cout << boost::format("Setting TX Bandwidth: %f MHz...") - % (bw / 1e6) + if (vm.count("bw")) { + std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % (bw / 1e6) << std::endl; radio_ctrl->set_tx_bandwidth(bw, radio_chan); std::cout << boost::format("Actual TX Bandwidth: %f MHz...") - % (radio_ctrl->get_tx_bandwidth(radio_chan) / 1e6) - << std::endl << std::endl; + % (radio_ctrl->get_tx_bandwidth(radio_chan) / 1e6) + << std::endl + << std::endl; } // Set the antenna @@ -172,13 +181,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // Connect Replay block to radio uhd::rfnoc::graph::sptr replay_graph = usrp->create_graph("rfnoc_replay"); usrp->clear(); - std::cout << "Connecting " << replay_ctrl->get_block_id() << " ==> " << radio_ctrl->get_block_id() << std::endl; - replay_graph->connect(replay_ctrl->get_block_id(), replay_chan, radio_ctrl->get_block_id(), radio_chan, replay_spp); + std::cout << "Connecting " << replay_ctrl->get_block_id() << " ==> " + << radio_ctrl->get_block_id() << std::endl; + replay_graph->connect(replay_ctrl->get_block_id(), + replay_chan, + radio_ctrl->get_block_id(), + radio_chan, + replay_spp); // Inform replay block that it has an RX streamer connected to it replay_ctrl->set_rx_streamer(true, replay_chan); @@ -193,20 +207,20 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) uhd::tx_streamer::sptr tx_stream; uhd::tx_metadata_t tx_md; - streamer_args["block_id"] = replay_ctrl->get_block_id().to_string(); + streamer_args["block_id"] = replay_ctrl->get_block_id().to_string(); streamer_args["block_port"] = str(boost::format("%d") % replay_chan); - stream_args.args = streamer_args; - tx_stream = usrp->get_tx_stream(stream_args); + stream_args.args = streamer_args; + tx_stream = usrp->get_tx_stream(stream_args); // Make sure that streamer SPP is a multiple of the Replay block word size size_t tx_spp = tx_stream->get_max_num_samps(); - if(tx_spp % samples_per_word != 0) { + if (tx_spp % samples_per_word != 0) { // Round SPP down to a multiple of the word size tx_spp = (tx_spp / samples_per_word) * samples_per_word; tx_stream.reset(); streamer_args["spp"] = boost::lexical_cast<std::string>(tx_spp); - stream_args.args = streamer_args; - tx_stream = usrp->get_tx_stream(stream_args); + stream_args.args = streamer_args; + tx_stream = usrp->get_tx_stream(stream_args); } cout << "Using streamer args: " << stream_args.args.to_string() << endl; @@ -228,7 +242,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) infile.seekg(0, std::ios::beg); // Calculate the number of 64-bit words and samples to replay - size_t words_to_replay = file_size / replay_word_size; + size_t words_to_replay = file_size / replay_word_size; size_t samples_to_replay = words_to_replay * replay_word_size / bytes_per_sample; // Create buffer @@ -254,15 +268,26 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) replay_ctrl->set_words_per_packet(replay_spp / samples_per_word, replay_chan); // Display replay configuration - cout << boost::format("Replay file size: %d bytes (%d qwords, %d samples)") - % (words_to_replay * replay_word_size) % words_to_replay % samples_to_replay + cout << boost::format("Replay file size: %d bytes (%d qwords, %d samples)") + % (words_to_replay * replay_word_size) % words_to_replay + % samples_to_replay << endl; - cout << boost::format("Record base address: 0x%X") % replay_ctrl->get_record_addr(replay_chan) << endl; - cout << boost::format("Record buffer size: %d bytes") % replay_ctrl->get_record_size(replay_chan) << endl; - cout << boost::format("Record fullness: %d") % replay_ctrl->get_record_fullness(replay_chan) << endl; - cout << boost::format("Play base address: 0x%X") % replay_ctrl->get_play_addr(replay_chan) << endl; - cout << boost::format("Play buffer size: %d bytes") % replay_ctrl->get_play_size(replay_chan) << endl; + cout << boost::format("Record base address: 0x%X") + % replay_ctrl->get_record_addr(replay_chan) + << endl; + cout << boost::format("Record buffer size: %d bytes") + % replay_ctrl->get_record_size(replay_chan) + << endl; + cout << boost::format("Record fullness: %d") + % replay_ctrl->get_record_fullness(replay_chan) + << endl; + cout << boost::format("Play base address: 0x%X") + % replay_ctrl->get_play_addr(replay_chan) + << endl; + cout << boost::format("Play buffer size: %d bytes") + % replay_ctrl->get_play_size(replay_chan) + << endl; // Restart record buffer repeatedly until no new data appears on the Replay // block's input. This will flush any data that was buffered on the input. @@ -278,12 +303,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) start_time = std::chrono::system_clock::now(); do { fullness = replay_ctrl->get_record_fullness(replay_chan); - if (fullness != 0) break; + if (fullness != 0) + break; time_diff = std::chrono::system_clock::now() - start_time; time_diff = std::chrono::duration_cast<std::chrono::milliseconds>(time_diff); } while (time_diff.count() < 250); } while (fullness); - + /////////////////////////////////////////////////////////////////////////// // Send data to replay (record the data) @@ -291,10 +317,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) cout << "Sending data to be recorded..." << endl; tx_md.start_of_burst = true; tx_md.end_of_burst = true; - size_t num_tx_samps = tx_stream->send(tx_buf_ptr, samples_to_replay, tx_md); + size_t num_tx_samps = tx_stream->send(tx_buf_ptr, samples_to_replay, tx_md); if (num_tx_samps != samples_to_replay) { - cout << boost::format("ERROR: Unable to send %d samples") % samples_to_replay << endl; + cout << boost::format("ERROR: Unable to send %d samples") % samples_to_replay + << endl; return EXIT_FAILURE; } @@ -303,7 +330,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Wait for data to be stored in on-board memory cout << "Waiting for recording to complete..." << endl; - while (replay_ctrl->get_record_fullness(replay_chan) < words_to_replay*replay_word_size); + while (replay_ctrl->get_record_fullness(replay_chan) + < words_to_replay * replay_word_size) + ; /////////////////////////////////////////////////////////////////////////// @@ -314,15 +343,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (nsamps <= 0) { // Replay the entire buffer over and over stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - stream_cmd.num_samps = words_to_replay; - cout << boost::format("Issuing replay command for %d words in continuous mode...") % stream_cmd.num_samps << endl; - } - else { + stream_cmd.num_samps = words_to_replay; + cout << boost::format("Issuing replay command for %d words in continuous mode...") + % stream_cmd.num_samps + << endl; + } else { // Replay nsamps, wrapping back to the start of the buffer if nsamps is // larger than the buffer size. stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE; - stream_cmd.num_samps = nsamps / samples_per_word; - cout << boost::format("Issuing replay command for %d words...") % stream_cmd.num_samps << endl; + stream_cmd.num_samps = nsamps / samples_per_word; + cout << boost::format("Issuing replay command for %d words...") + % stream_cmd.num_samps + << endl; } stream_cmd.stream_now = true; replay_ctrl->issue_stream_cmd(stream_cmd, replay_chan); @@ -335,7 +367,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::signal(SIGINT, &sig_int_handler); cout << "Replaying data (Press Ctrl+C to stop)..." << endl; - while (not stop_signal_called); + while (not stop_signal_called) + ; // Remove SIGINT handler std::signal(SIGINT, SIG_DFL); @@ -359,11 +392,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) uint16_t prev_packet_count, packet_count; cout << "Waiting for replay data to flush... "; - prev_packet_count = replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) >> 32; - while(true) { + prev_packet_count = + replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) + >> 32; + while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); - packet_count = replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) >> 32; - if (packet_count == prev_packet_count) break; + packet_count = + replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) + >> 32; + if (packet_count == prev_packet_count) + break; prev_packet_count = packet_count; } diff --git a/host/examples/rfnoc_nullsource_ce_rx.cpp b/host/examples/rfnoc_nullsource_ce_rx.cpp index f6aa6e1a4..16eb49c7b 100644 --- a/host/examples/rfnoc_nullsource_ce_rx.cpp +++ b/host/examples/rfnoc_nullsource_ce_rx.cpp @@ -21,36 +21,39 @@ // and then streams the result to the host, writing it into a file. #include <uhd/device3.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/exception.hpp> #include <uhd/rfnoc/block_ctrl.hpp> #include <uhd/rfnoc/null_block_ctrl.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> -#include <fstream> -#include <csignal> +#include <boost/program_options.hpp> +#include <chrono> #include <complex> +#include <csignal> +#include <fstream> +#include <iostream> #include <thread> -#include <chrono> namespace po = boost::program_options; static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} -template<typename samp_type> void recv_to_file( - uhd::rx_streamer::sptr rx_stream, - const std::string &file, +template <typename samp_type> +void recv_to_file(uhd::rx_streamer::sptr rx_stream, + const std::string& file, size_t samps_per_buff, unsigned long long num_requested_samples, - double time_requested = 0.0, - bool bw_summary = false, - bool stats = false, - bool continue_on_bad_packet = false -) { + double time_requested = 0.0, + bool bw_summary = false, + bool stats = false, + bool continue_on_bad_packet = false) +{ unsigned long long num_total_samps = 0; uhd::rx_metadata_t md; @@ -61,14 +64,13 @@ template<typename samp_type> void recv_to_file( } bool overflow_message = true; - //setup streaming - uhd::stream_cmd_t stream_cmd((num_requested_samples == 0)? - uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS: - uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE - ); - stream_cmd.num_samps = num_requested_samples; + // setup streaming + uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) + ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS + : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = num_requested_samples; stream_cmd.stream_now = true; - stream_cmd.time_spec = uhd::time_spec_t(); + stream_cmd.time_spec = uhd::time_spec_t(); std::cout << "Issuing start stream cmd" << std::endl; // This actually goes to the null source; the processing block // should propagate it. @@ -77,19 +79,14 @@ template<typename samp_type> void recv_to_file( const auto start_time = std::chrono::steady_clock::now(); const auto stop_time = - start_time - + std::chrono::milliseconds(int64_t(1000 * time_requested)); + start_time + std::chrono::milliseconds(int64_t(1000 * time_requested)); // Track time and samps between updating the BW summary - auto last_update = start_time; + auto last_update = start_time; unsigned long long last_update_samps = 0; - while( - not stop_signal_called - and (num_requested_samples != num_total_samps - or num_requested_samples == 0) - and (time_requested == 0.0 - or std::chrono::steady_clock::now() <= stop_time) - ) { + while (not stop_signal_called + and (num_requested_samples != num_total_samps or num_requested_samples == 0) + and (time_requested == 0.0 or std::chrono::steady_clock::now() <= stop_time)) { const auto now = std::chrono::steady_clock::now(); size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md, 3.0); @@ -98,28 +95,27 @@ template<typename samp_type> void recv_to_file( std::cout << "Timeout while streaming" << std::endl; break; } - if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW){ - if (overflow_message){ + if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { + if (overflow_message) { overflow_message = false; std::cerr << "Got an overflow indication. If writing to disk, your\n" "write medium may not be able to keep up.\n"; } continue; } - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { const auto error = std::string("Receiver error: ") + md.strerror(); - if (continue_on_bad_packet){ + if (continue_on_bad_packet) { std::cerr << error << std::endl; continue; - } - else { + } else { throw std::runtime_error(error); } } num_total_samps += num_rx_samps; if (outfile.is_open()) { - outfile.write((const char*)&buff.front(), num_rx_samps*sizeof(samp_type)); + outfile.write((const char*)&buff.front(), num_rx_samps * sizeof(samp_type)); } if (bw_summary) { @@ -128,11 +124,10 @@ template<typename samp_type> void recv_to_file( if (time_since_last_update > std::chrono::seconds(1)) { const double time_since_last_update_s = std::chrono::duration<double>(time_since_last_update).count(); - const double rate = - double(last_update_samps) / time_since_last_update_s; - std::cout << "\t" << (rate/1e6) << " Msps" << std::endl; + const double rate = double(last_update_samps) / time_since_last_update_s; + std::cout << "\t" << (rate / 1e6) << " Msps" << std::endl; last_update_samps = 0; - last_update = now; + last_update = now; } } } @@ -151,13 +146,11 @@ template<typename samp_type> void recv_to_file( std::cout << std::endl; const double actual_duration_seconds = std::chrono::duration<float>(actual_stop_time - start_time).count(); - std::cout - << boost::format("Received %d samples in %f seconds") - % num_total_samps - % actual_duration_seconds - << std::endl; - const double rate = (double) num_total_samps / actual_duration_seconds; - std::cout << (rate/1e6) << " Msps" << std::endl; + std::cout << boost::format("Received %d samples in %f seconds") % num_total_samps + % actual_duration_seconds + << std::endl; + const double rate = (double)num_total_samps / actual_duration_seconds; + std::cout << (rate / 1e6) << " Msps" << std::endl; } } @@ -211,16 +204,16 @@ void pretty_print_flow_graph(std::vector<std::string> blocks) } ///////////////////// MAIN //////////////////////////////////////////////////// -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, file, format, nullid, blockid, blockid2; size_t total_num_samps, spb, spp; double rate, total_time, setup_time, block_rate; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -248,17 +241,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 - << "[RFNOC] Connect a null source to another (processing) block, " - "and stream the result to file." - << desc << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << "[RFNOC] Connect a null source to another (processing) block, " + "and stream the result to file." + << desc << std::endl; return EXIT_SUCCESS; } - bool bw_summary = vm.count("progress") > 0; - bool stats = vm.count("stats") > 0; + bool bw_summary = vm.count("progress") > 0; + bool stats = vm.count("stats") > 0; bool continue_on_bad_packet = vm.count("continue") > 0; // Check settings @@ -267,7 +259,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) return ~0; } if (not uhd::rfnoc::block_id_t::is_valid_block_id(blockid)) { - std::cout << "Must specify a valid block ID for the processing block." << std::endl; + std::cout << "Must specify a valid block ID for the processing block." + << std::endl; return ~0; } if (not blockid2.empty()) { @@ -290,7 +283,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::cout << "Creating the USRP device with args: " << args << std::endl; uhd::device3::sptr usrp = uhd::device3::make(args); - std::this_thread::sleep_for( //allow for some setup time + std::this_thread::sleep_for( // allow for some setup time std::chrono::milliseconds(int64_t(setup_time * 1000))); // Reset device streaming state usrp->clear(); @@ -356,18 +349,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } // Or, if our block has its own getters + setters, you can call those: - std::cout << str(boost::format("Requesting rate: %.2f Msps (%.2f MByte/s).") % (rate / 1e6) % (rate * 4 / 1e6)) << std::endl; + std::cout << str(boost::format("Requesting rate: %.2f Msps (%.2f MByte/s).") + % (rate / 1e6) % (rate * 4 / 1e6)) + << std::endl; const size_t SAMPLES_PER_LINE = 2; null_src_ctrl->set_line_rate(rate / SAMPLES_PER_LINE, block_rate); // Now, it's possible that this requested rate is not available. // Let's read back the true rate with the getter: - double actual_rate_mega = null_src_ctrl->get_line_rate(block_rate) / 1e6 * SAMPLES_PER_LINE; - std::cout - << str( - boost::format("Actually got rate: %.2f Msps (%.2f MByte/s).") - % actual_rate_mega % (actual_rate_mega * BYTES_PER_SAMPLE) - ) - << std::endl; + double actual_rate_mega = + null_src_ctrl->get_line_rate(block_rate) / 1e6 * SAMPLES_PER_LINE; + std::cout << str(boost::format("Actually got rate: %.2f Msps (%.2f MByte/s).") + % actual_rate_mega % (actual_rate_mega * BYTES_PER_SAMPLE)) + << std::endl; ///////////////////////////////////////////////////////////////////////// @@ -376,33 +369,42 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::cout << "Connecting blocks..." << std::endl; if (proc_block_ctrl) { rx_graph->connect( // Yes, it's that easy! - null_src_ctrl->get_block_id(), - proc_block_ctrl->get_block_id() - ); + null_src_ctrl->get_block_id(), + proc_block_ctrl->get_block_id()); } if (proc_block_ctrl2 and proc_block_ctrl) { rx_graph->connect( - proc_block_ctrl->get_block_id(), - proc_block_ctrl2->get_block_id() - ); + proc_block_ctrl->get_block_id(), proc_block_ctrl2->get_block_id()); } ///////////////////////////////////////////////////////////////////////// //////// 6. Spawn receiver ////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// uhd::stream_args_t stream_args(format, "sc16"); - stream_args.args = stream_args_args; + stream_args.args = stream_args_args; stream_args.args["spp"] = std::to_string(spp); - UHD_LOGGER_DEBUG("RFNOC") << "Using streamer args: " << stream_args.args.to_string() << std::endl; + UHD_LOGGER_DEBUG("RFNOC") << "Using streamer args: " << stream_args.args.to_string() + << std::endl; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); #define recv_to_file_args() \ - (rx_stream, file, spb, total_num_samps, total_time, bw_summary, stats, continue_on_bad_packet) - //recv to file - if (format == "fc64") recv_to_file<std::complex<double> >recv_to_file_args(); - else if (format == "fc32") recv_to_file<std::complex<float> >recv_to_file_args(); - else if (format == "sc16") recv_to_file<std::complex<short> >recv_to_file_args(); - else throw std::runtime_error("Unknown type sample type: " + format); + (rx_stream, \ + file, \ + spb, \ + total_num_samps, \ + total_time, \ + bw_summary, \ + stats, \ + continue_on_bad_packet) + // recv to file + if (format == "fc64") + recv_to_file<std::complex<double>> recv_to_file_args(); + else if (format == "fc32") + recv_to_file<std::complex<float>> recv_to_file_args(); + else if (format == "sc16") + recv_to_file<std::complex<short>> recv_to_file_args(); + else + throw std::runtime_error("Unknown type sample type: " + format); // Finished! std::cout << std::endl << "Done!" << std::endl << std::endl; diff --git a/host/examples/rfnoc_radio_loopback.cpp b/host/examples/rfnoc_radio_loopback.cpp index f773cfe90..848f9c4da 100644 --- a/host/examples/rfnoc_radio_loopback.cpp +++ b/host/examples/rfnoc_radio_loopback.cpp @@ -13,9 +13,9 @@ #include <uhd/utils/math.hpp> #include <uhd/utils/safe_main.hpp> #include <boost/program_options.hpp> -#include <iostream> -#include <csignal> #include <chrono> +#include <csignal> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -25,20 +25,23 @@ using uhd::rfnoc::radio_ctrl; * SIGINT handling ***************************************************************************/ static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} /**************************************************************************** * main ***************************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { - //variables to be set by po + // variables to be set by po std::string args, rx_args, tx_args, rx_ant, tx_ant, rx_blockid, tx_blockid, ref; size_t total_num_samps, spp, rx_chan, tx_chan, tx_delay; double rate, rx_freq, tx_freq, rx_gain, tx_gain, bw, total_time, setup_time; bool rx_timestamps; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -72,7 +75,7 @@ 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 + // print the help message if (vm.count("help")) { std::cout << boost::format("RFNoC: Radio loopback test %s") % desc << std::endl; std::cout @@ -84,7 +87,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Create a device session 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; auto dev = boost::dynamic_pointer_cast<uhd::device3>(uhd::device::make(args)); if (not dev) { std::cout << "Error: Could not find an RFNoC-compatible device." << std::endl; @@ -93,13 +97,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Access block controllers if (not dev->has_block<uhd::rfnoc::radio_ctrl>(rx_blockid) - or not dev->has_block<uhd::rfnoc::radio_ctrl>(tx_blockid)) { + or not dev->has_block<uhd::rfnoc::radio_ctrl>(tx_blockid)) { std::cout << "Error: Could not access at least one of these blocks:\n" - << "- " << rx_blockid - << "- " << tx_blockid - << std::endl; - std::cout << "Please confirm these blocks are actually available on the current loaded device." - << std::endl; + << "- " << rx_blockid << "- " << tx_blockid << std::endl; + std::cout << "Please confirm these blocks are actually available on the current " + "loaded device." + << std::endl; return EXIT_FAILURE; } auto rx_radio_ctrl = dev->get_block_ctrl<radio_ctrl>(rx_blockid); @@ -110,58 +113,65 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) rx_radio_ctrl->set_args(rx_args); if (spp) { rx_radio_ctrl->set_arg<int>("spp", spp, rx_chan); - } - std::cout << "Setting Rx rate: " << (rate/1e6) << " Msps" << std::endl; + std::cout << "Setting Rx rate: " << (rate / 1e6) << " Msps" << std::endl; double actual_rx_rate = rx_radio_ctrl->set_rate(rate); - std::cout << "Actual Rx rate: " << (actual_rx_rate/1e6) << " Msps" << std::endl; - std::cout << "Setting Rx frequency: " << (rx_freq/1e6) << " MHz." << std::endl; - std::cout << "Actual Rx frequency: " << (rx_radio_ctrl->set_rx_frequency(rx_freq, rx_chan)/1e6) << " MHz." << std::endl; + std::cout << "Actual Rx rate: " << (actual_rx_rate / 1e6) << " Msps" << std::endl; + std::cout << "Setting Rx frequency: " << (rx_freq / 1e6) << " MHz." << std::endl; + std::cout << "Actual Rx frequency: " + << (rx_radio_ctrl->set_rx_frequency(rx_freq, rx_chan) / 1e6) << " MHz." + << std::endl; if (rx_gain) { std::cout << "Setting Rx gain: " << (rx_gain) << " dB." << std::endl; - std::cout << "Actual Rx gain: " << (rx_radio_ctrl->set_rx_gain(rx_gain, rx_chan)) << " dB." << std::endl; + std::cout << "Actual Rx gain: " << (rx_radio_ctrl->set_rx_gain(rx_gain, rx_chan)) + << " dB." << std::endl; } if (not rx_ant.empty()) { std::cout << "Setting Rx antenna: " << (rx_ant) << "." << std::endl; rx_radio_ctrl->set_rx_antenna(rx_ant, rx_chan); - std::cout << "Actual Rx antenna: " << rx_radio_ctrl->get_rx_antenna(rx_chan) << "." << std::endl; + std::cout << "Actual Rx antenna: " << rx_radio_ctrl->get_rx_antenna(rx_chan) + << "." << std::endl; } if (!rx_timestamps) { - std::cout << "Disabling timestamps on RX... (direct loopback, may underrun)" << std::endl; + std::cout << "Disabling timestamps on RX... (direct loopback, may underrun)" + << std::endl; } rx_radio_ctrl->enable_rx_timestamps(rx_timestamps, 0); // Configure Tx radio std::cout << "Configuring Tx radio..." << std::endl; tx_radio_ctrl->set_args(tx_args); - std::cout << "Setting Tx rate: " << (rate/1e6) << " Msps" << std::endl; + std::cout << "Setting Tx rate: " << (rate / 1e6) << " Msps" << std::endl; double actual_tx_rate = tx_radio_ctrl->set_rate(rate); - std::cout << "Actual Tx rate: " << (actual_tx_rate/1e6) << " Msps" << std::endl; - std::cout << "Setting Tx frequency: " << (tx_freq/1e6) << " MHz." << std::endl; - std::cout << "Actual Tx frequency: " << (tx_radio_ctrl->set_tx_frequency(tx_freq, tx_chan)/1e6) << " MHz." << std::endl; + std::cout << "Actual Tx rate: " << (actual_tx_rate / 1e6) << " Msps" << std::endl; + std::cout << "Setting Tx frequency: " << (tx_freq / 1e6) << " MHz." << std::endl; + std::cout << "Actual Tx frequency: " + << (tx_radio_ctrl->set_tx_frequency(tx_freq, tx_chan) / 1e6) << " MHz." + << std::endl; if (tx_gain) { std::cout << "Setting Tx gain: " << (tx_gain) << " dB." << std::endl; - std::cout << "Actual Tx gain: " << (tx_radio_ctrl->set_tx_gain(tx_gain, tx_chan)) << " dB." << std::endl; + std::cout << "Actual Tx gain: " << (tx_radio_ctrl->set_tx_gain(tx_gain, tx_chan)) + << " dB." << std::endl; } if (not tx_ant.empty()) { std::cout << "Setting Tx antenna: " << (tx_ant) << "." << std::endl; tx_radio_ctrl->set_tx_antenna(tx_ant, tx_chan); - std::cout << "Actual Tx antenna: " << tx_radio_ctrl->get_tx_antenna(tx_chan) << "." << std::endl; + std::cout << "Actual Tx antenna: " << tx_radio_ctrl->get_tx_antenna(tx_chan) + << "." << std::endl; } // Compare rates if (not uhd::math::frequencies_are_equal(actual_rx_rate, actual_tx_rate)) { - std::cout << "Error: Failed to set receive and transmit radios to same sampling rate!" << std::endl; + std::cout + << "Error: Failed to set receive and transmit radios to same sampling rate!" + << std::endl; return EXIT_FAILURE; } // Create graph and connect blocks uhd::rfnoc::graph::sptr graph = dev->create_graph("radio_loopback"); std::cout << "Connecting radios..." << std::endl; try { - graph->connect( - rx_blockid, rx_chan, - tx_blockid, tx_chan - ); - } catch (const uhd::runtime_error &ex) { + graph->connect(rx_blockid, rx_chan, tx_blockid, tx_chan); + } catch (const uhd::runtime_error& ex) { std::cout << "Error connecting blocks: " << std::endl; std::cout << ex.what() << std::endl; return EXIT_FAILURE; @@ -170,8 +180,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) rx_radio_ctrl->set_rx_streamer(true, rx_chan); // Allow for some setup time - std::this_thread::sleep_for( - std::chrono::milliseconds(int64_t(setup_time * 1000))); + std::this_thread::sleep_for(std::chrono::milliseconds(int64_t(setup_time * 1000))); // Arm SIGINT handler std::signal(SIGINT, &sig_int_handler); @@ -179,17 +188,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Calculate timeout and set timers if (total_time == 0 and total_num_samps > 0) { const double buffer_time = 1.0; // seconds - total_time = (1.0/rate) * total_num_samps + buffer_time; + total_time = (1.0 / rate) * total_num_samps + buffer_time; } // Start streaming - uhd::stream_cmd_t stream_cmd((total_num_samps == 0)? - uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS: - uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE - ); - stream_cmd.num_samps = size_t(total_num_samps); + uhd::stream_cmd_t stream_cmd((total_num_samps == 0) + ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS + : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = size_t(total_num_samps); stream_cmd.stream_now = true; - stream_cmd.time_spec = uhd::time_spec_t(); + stream_cmd.time_spec = uhd::time_spec_t(); std::cout << "Issuing start stream cmd..." << std::endl; rx_radio_ctrl->issue_stream_cmd(stream_cmd, rx_chan); std::cout << "Wait..." << std::endl; @@ -208,4 +216,3 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) return EXIT_SUCCESS; } - diff --git a/host/examples/rfnoc_rx_to_file.cpp b/host/examples/rfnoc_rx_to_file.cpp index 8993d52b7..98b0a5479 100644 --- a/host/examples/rfnoc_rx_to_file.cpp +++ b/host/examples/rfnoc_rx_to_file.cpp @@ -15,42 +15,45 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/types/tune_request.hpp> -#include <uhd/types/sensors.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/device3.hpp> +#include <uhd/exception.hpp> #include <uhd/rfnoc/radio_ctrl.hpp> #include <uhd/rfnoc/source_block_ctrl_base.hpp> -#include <uhd/exception.hpp> -#include <boost/program_options.hpp> +#include <uhd/types/sensors.hpp> +#include <uhd/types/tune_request.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> -#include <fstream> -#include <csignal> +#include <boost/program_options.hpp> +#include <chrono> #include <complex> +#include <csignal> +#include <fstream> +#include <iostream> #include <thread> -#include <chrono> namespace po = boost::program_options; -const int64_t UPDATE_INTERVAL = 1; //1 second update interval for BW summary +const int64_t UPDATE_INTERVAL = 1; // 1 second update interval for BW summary static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} -template<typename samp_type> void recv_to_file( - uhd::rx_streamer::sptr rx_stream, - const std::string &file, +template <typename samp_type> +void recv_to_file(uhd::rx_streamer::sptr rx_stream, + const std::string& file, const size_t samps_per_buff, const double rx_rate, const unsigned long long num_requested_samples, - double time_requested = 0.0, - bool bw_summary = false, - bool stats = false, - bool enable_size_map = false, - bool continue_on_bad_packet = false -){ + double time_requested = 0.0, + bool bw_summary = false, + bool stats = false, + bool enable_size_map = false, + bool continue_on_bad_packet = false) +{ unsigned long long num_total_samps = 0; uhd::rx_metadata_t md; @@ -61,65 +64,61 @@ template<typename samp_type> void recv_to_file( } bool overflow_message = true; - //setup streaming - uhd::stream_cmd_t stream_cmd((num_requested_samples == 0)? - uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS: - uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE - ); - stream_cmd.num_samps = size_t(num_requested_samples); + // setup streaming + uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) + ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS + : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = size_t(num_requested_samples); stream_cmd.stream_now = true; - stream_cmd.time_spec = uhd::time_spec_t(); + stream_cmd.time_spec = uhd::time_spec_t(); std::cout << "Issuing stream cmd" << std::endl; rx_stream->issue_stream_cmd(stream_cmd); const auto start_time = std::chrono::steady_clock::now(); const auto stop_time = - start_time - + std::chrono::milliseconds(int64_t(1000 * time_requested)); + start_time + std::chrono::milliseconds(int64_t(1000 * time_requested)); // Track time and samps between updating the BW summary - auto last_update = start_time; + auto last_update = start_time; unsigned long long last_update_samps = 0; - typedef std::map<size_t,size_t> SizeMap; + typedef std::map<size_t, size_t> SizeMap; SizeMap mapSizes; // Run this loop until either time expired (if a duration was given), until // the requested number of samples were collected (if such a number was // given), or until Ctrl-C was pressed. while (not stop_signal_called - and (num_requested_samples != num_total_samps - or num_requested_samples == 0) - and (time_requested == 0.0 - or std::chrono::steady_clock::now() <= stop_time) - ) { + and (num_requested_samples != num_total_samps or num_requested_samples == 0) + and (time_requested == 0.0 or std::chrono::steady_clock::now() <= stop_time)) { const auto now = std::chrono::steady_clock::now(); - size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md, 3.0, enable_size_map); + size_t num_rx_samps = + rx_stream->recv(&buff.front(), buff.size(), md, 3.0, enable_size_map); if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { std::cout << boost::format("Timeout while streaming") << std::endl; break; } - if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW){ + if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { if (overflow_message) { overflow_message = false; - std::cerr << boost::format( - "Got an overflow indication. Please consider the following:\n" - " Your write medium must sustain a rate of %fMB/s.\n" - " Dropped samples will not be written to the file.\n" - " Please modify this example for your purposes.\n" - " This message will not appear again.\n" - ) % (rx_rate*sizeof(samp_type)/1e6); + std::cerr + << boost::format( + "Got an overflow indication. Please consider the following:\n" + " Your write medium must sustain a rate of %fMB/s.\n" + " Dropped samples will not be written to the file.\n" + " Please modify this example for your purposes.\n" + " This message will not appear again.\n") + % (rx_rate * sizeof(samp_type) / 1e6); } continue; } - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::string error = str(boost::format("Receiver error: %s") % md.strerror()); - if (continue_on_bad_packet){ + if (continue_on_bad_packet) { std::cerr << error << std::endl; continue; - } - else + } else throw std::runtime_error(error); } @@ -133,7 +132,7 @@ template<typename samp_type> void recv_to_file( num_total_samps += num_rx_samps; if (outfile.is_open()) { - outfile.write((const char*)&buff.front(), num_rx_samps*sizeof(samp_type)); + outfile.write((const char*)&buff.front(), num_rx_samps * sizeof(samp_type)); } if (bw_summary) { @@ -142,14 +141,12 @@ template<typename samp_type> void recv_to_file( if (time_since_last_update > std::chrono::seconds(UPDATE_INTERVAL)) { const double time_since_last_update_s = std::chrono::duration<double>(time_since_last_update).count(); - const double rate = - double(last_update_samps) / time_since_last_update_s; - std::cout << "\t" << (rate/1e6) << " MSps" << std::endl; + const double rate = double(last_update_samps) / time_since_last_update_s; + std::cout << "\t" << (rate / 1e6) << " MSps" << std::endl; last_update_samps = 0; - last_update = now; + last_update = now; } } - } const auto actual_stop_time = std::chrono::steady_clock::now(); @@ -161,7 +158,7 @@ template<typename samp_type> void recv_to_file( int num_post_samps = 0; do { num_post_samps = rx_stream->recv(&buff.front(), buff.size(), md, 3.0); - } while(num_post_samps and md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE); + } while (num_post_samps and md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE); if (outfile.is_open()) outfile.close(); @@ -172,13 +169,11 @@ template<typename samp_type> void recv_to_file( const double actual_duration_seconds = std::chrono::duration<float>(actual_stop_time - start_time).count(); - std::cout - << boost::format("Received %d samples in %f seconds") - % num_total_samps - % actual_duration_seconds - << std::endl; + std::cout << boost::format("Received %d samples in %f seconds") % num_total_samps + % actual_duration_seconds + << std::endl; const double rate = (double)num_total_samps / actual_duration_seconds; - std::cout << (rate/1e6) << " MSps" << std::endl; + std::cout << (rate / 1e6) << " MSps" << std::endl; if (enable_size_map) { std::cout << std::endl; @@ -189,23 +184,26 @@ template<typename samp_type> void recv_to_file( } } -typedef boost::function<uhd::sensor_value_t (const std::string&)> get_sensor_fn_t; +typedef boost::function<uhd::sensor_value_t(const std::string&)> get_sensor_fn_t; -bool check_locked_sensor(std::vector<std::string> sensor_names, const char* sensor_name, get_sensor_fn_t get_sensor_fn, double setup_time){ - if (std::find(sensor_names.begin(), sensor_names.end(), sensor_name) == sensor_names.end()) +bool check_locked_sensor(std::vector<std::string> sensor_names, + const char* sensor_name, + get_sensor_fn_t get_sensor_fn, + double setup_time) +{ + if (std::find(sensor_names.begin(), sensor_names.end(), sensor_name) + == sensor_names.end()) return false; - auto setup_timeout = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(int64_t(setup_time * 1000)); + auto setup_timeout = std::chrono::steady_clock::now() + + std::chrono::milliseconds(int64_t(setup_time * 1000)); bool lock_detected = false; std::cout << boost::format("Waiting for \"%s\": ") % sensor_name; std::cout.flush(); while (true) { - if (lock_detected and - (std::chrono::steady_clock::now() > setup_timeout)) { + if (lock_detected and (std::chrono::steady_clock::now() > setup_timeout)) { std::cout << " locked." << std::endl; break; } @@ -213,14 +211,13 @@ bool check_locked_sensor(std::vector<std::string> sensor_names, const char* sens std::cout << "+"; std::cout.flush(); lock_detected = true; - } - else { + } else { if (std::chrono::steady_clock::now() > setup_timeout) { std::cout << std::endl; - throw std::runtime_error(str( - boost::format("timed out waiting for consecutive locks on sensor \"%s\"") - % sensor_name - )); + throw std::runtime_error( + str(boost::format( + "timed out waiting for consecutive locks on sensor \"%s\"") + % sensor_name)); } std::cout << "_"; std::cout.flush(); @@ -232,15 +229,17 @@ bool check_locked_sensor(std::vector<std::string> sensor_names, const char* sens return true; } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po - std::string args, file, format, ant, subdev, ref, wirefmt, streamargs, radio_args, block_id, block_args; + // variables to be set by po + std::string args, file, format, ant, subdev, ref, wirefmt, streamargs, radio_args, + block_id, block_args; size_t total_num_samps, spb, radio_id, radio_chan; double rate, freq, gain, bw, total_time, setup_time; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -280,26 +279,27 @@ 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 + // print the help message if (vm.count("help")) { std::cout << boost::format("UHD/RFNoC RX samples to file %s") % desc << std::endl; - std::cout - << std::endl - << "This application streams data from a single channel of a USRP device to a file.\n" - << std::endl; + std::cout << std::endl + << "This application streams data from a single channel of a USRP " + "device to a file.\n" + << std::endl; return ~0; } bool bw_summary = vm.count("progress") > 0; - bool stats = vm.count("stats") > 0; + bool stats = vm.count("stats") > 0; if (vm.count("null") > 0) { file = ""; } - bool enable_size_map = vm.count("sizemap") > 0; + bool enable_size_map = vm.count("sizemap") > 0; bool continue_on_bad_packet = vm.count("continue") > 0; if (enable_size_map) { - std::cout << "Packet size tracking enabled - will only recv one packet at a time!" << std::endl; + std::cout << "Packet size tracking enabled - will only recv one packet at a time!" + << std::endl; } if (format != "sc16" and format != "fc32" and format != "fc64") { @@ -311,12 +311,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ * Create device and block controls ***********************************************************************/ 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::device3::sptr usrp = uhd::device3::make(args); // Create handle for radio object uhd::rfnoc::block_id_t radio_ctrl_id(0, "Radio", radio_id); // This next line will fail if the radio is not actually available - uhd::rfnoc::radio_ctrl::sptr radio_ctrl = usrp->get_block_ctrl< uhd::rfnoc::radio_ctrl >(radio_ctrl_id); + uhd::rfnoc::radio_ctrl::sptr radio_ctrl = + usrp->get_block_ctrl<uhd::rfnoc::radio_ctrl>(radio_ctrl_id); std::cout << "Using radio " << radio_id << ", channel " << radio_chan << std::endl; /************************************************************************ @@ -324,60 +326,73 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ***********************************************************************/ radio_ctrl->set_args(radio_args); if (vm.count("ref")) { - std::cout << "TODO -- Need to implement API call to set clock source." << std::endl; - //Lock mboard clocks TODO - //usrp->set_clock_source(ref); + std::cout << "TODO -- Need to implement API call to set clock source." + << std::endl; + // Lock mboard clocks TODO + // usrp->set_clock_source(ref); } - //set the sample rate - if (rate <= 0.0){ + // set the sample rate + if (rate <= 0.0) { std::cerr << "Please specify a valid sample rate" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; radio_ctrl->set_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (radio_ctrl->get_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") + % (radio_ctrl->get_rate() / 1e6) + << std::endl + << std::endl; - //set the center frequency + // set the center frequency if (vm.count("freq")) { - std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; + std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq / 1e6) + << std::endl; uhd::tune_request_t tune_request(freq); if (vm.count("int-n")) { - //tune_request.args = uhd::device_addr_t("mode_n=integer"); TODO + // tune_request.args = uhd::device_addr_t("mode_n=integer"); TODO } radio_ctrl->set_rx_frequency(freq, radio_chan); - std::cout << boost::format("Actual RX Freq: %f MHz...") % (radio_ctrl->get_rx_frequency(radio_chan)/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Freq: %f MHz...") + % (radio_ctrl->get_rx_frequency(radio_chan) / 1e6) + << std::endl + << std::endl; } - //set the rf gain + // set the rf gain if (vm.count("gain")) { std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; radio_ctrl->set_rx_gain(gain, radio_chan); - std::cout << boost::format("Actual RX Gain: %f dB...") % radio_ctrl->get_rx_gain(radio_chan) << std::endl << std::endl; + std::cout << boost::format("Actual RX Gain: %f dB...") + % radio_ctrl->get_rx_gain(radio_chan) + << std::endl + << std::endl; } - //set the IF filter bandwidth + // set the IF filter bandwidth if (vm.count("bw")) { - //std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << std::endl; - //radio_ctrl->set_rx_bandwidth(bw, radio_chan); // TODO - //std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (radio_ctrl->get_rx_bandwidth(radio_chan)/1e6) << std::endl << std::endl; + // std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << + // std::endl; radio_ctrl->set_rx_bandwidth(bw, radio_chan); // TODO std::cout << + // boost::format("Actual RX Bandwidth: %f MHz...") % + // (radio_ctrl->get_rx_bandwidth(radio_chan)/1e6) << std::endl << std::endl; } - //set the antenna + // set the antenna if (vm.count("ant")) { radio_ctrl->set_rx_antenna(ant, radio_chan); } - std::this_thread::sleep_for( - std::chrono::milliseconds(int64_t(1000 * setup_time)) - ); + std::this_thread::sleep_for(std::chrono::milliseconds(int64_t(1000 * setup_time))); - //check Ref and LO Lock detect - if (not vm.count("skip-lo")){ + // check Ref and LO Lock detect + if (not vm.count("skip-lo")) { // TODO - //check_locked_sensor(usrp->get_rx_sensor_names(0), "lo_locked", boost::bind(&uhd::usrp::multi_usrp::get_rx_sensor, usrp, _1, radio_id), setup_time); - //if (ref == "external") - //check_locked_sensor(usrp->get_mboard_sensor_names(0), "ref_locked", boost::bind(&uhd::usrp::multi_usrp::get_mboard_sensor, usrp, _1, radio_id), setup_time); + // check_locked_sensor(usrp->get_rx_sensor_names(0), "lo_locked", + // boost::bind(&uhd::usrp::multi_usrp::get_rx_sensor, usrp, _1, radio_id), + // setup_time); if (ref == "external") + // check_locked_sensor(usrp->get_mboard_sensor_names(0), "ref_locked", + // boost::bind(&uhd::usrp::multi_usrp::get_mboard_sensor, usrp, _1, radio_id), + // setup_time); } size_t spp = radio_ctrl->get_arg<int>("spp"); @@ -392,12 +407,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ // Set the stream args on the radio: if (block_id.empty()) { // If no extra block is required, connect to the radio: - streamer_args["block_id"] = radio_ctrl_id.to_string(); + streamer_args["block_id"] = radio_ctrl_id.to_string(); streamer_args["block_port"] = str(boost::format("%d") % radio_chan); } else { // Otherwise, see if the requested block exists and connect it to the radio: if (not usrp->has_block(block_id)) { - std::cout << "Block does not exist on current device: " << block_id << std::endl; + std::cout << "Block does not exist on current device: " << block_id + << std::endl; return EXIT_FAILURE; } @@ -409,17 +425,20 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ blk_ctrl->set_args(uhd::device_addr_t(block_args)); } // Connect: - std::cout << "Connecting " << radio_ctrl_id << " ==> " << blk_ctrl->get_block_id() << std::endl; - rx_graph->connect(radio_ctrl_id, radio_chan, blk_ctrl->get_block_id(), uhd::rfnoc::ANY_PORT); + std::cout << "Connecting " << radio_ctrl_id << " ==> " << blk_ctrl->get_block_id() + << std::endl; + rx_graph->connect( + radio_ctrl_id, radio_chan, blk_ctrl->get_block_id(), uhd::rfnoc::ANY_PORT); streamer_args["block_id"] = blk_ctrl->get_block_id().to_string(); spp = blk_ctrl->get_args().cast<size_t>("spp", spp); } - //create a receive streamer + // create a receive streamer std::cout << "Samples per packet: " << spp << std::endl; - uhd::stream_args_t stream_args(format, "sc16"); // We should read the wire format from the blocks - stream_args.args = streamer_args; + uhd::stream_args_t stream_args( + format, "sc16"); // We should read the wire format from the blocks + stream_args.args = streamer_args; stream_args.args["spp"] = boost::lexical_cast<std::string>(spp); std::cout << "Using streamer args: " << stream_args.args.to_string() << std::endl; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); @@ -429,14 +448,27 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "Press Ctrl + C to stop streaming..." << std::endl; } #define recv_to_file_args() \ - (rx_stream, file, spb, rate, total_num_samps, total_time, bw_summary, stats, enable_size_map, continue_on_bad_packet) - //recv to file - if (format == "fc64") recv_to_file<std::complex<double> >recv_to_file_args(); - else if (format == "fc32") recv_to_file<std::complex<float> >recv_to_file_args(); - else if (format == "sc16") recv_to_file<std::complex<short> >recv_to_file_args(); - else throw std::runtime_error("Unknown data format: " + format); - - //finished + (rx_stream, \ + file, \ + spb, \ + rate, \ + total_num_samps, \ + total_time, \ + bw_summary, \ + stats, \ + enable_size_map, \ + continue_on_bad_packet) + // recv to file + if (format == "fc64") + recv_to_file<std::complex<double>> recv_to_file_args(); + else if (format == "fc32") + recv_to_file<std::complex<float>> recv_to_file_args(); + else if (format == "sc16") + recv_to_file<std::complex<short>> recv_to_file_args(); + else + throw std::runtime_error("Unknown data format: " + format); + + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/rx_ascii_art_dft.cpp b/host/examples/rx_ascii_art_dft.cpp index 8e4179fe3..a82d8ee49 100644 --- a/host/examples/rx_ascii_art_dft.cpp +++ b/host/examples/rx_ascii_art_dft.cpp @@ -5,33 +5,34 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/multi_usrp.hpp> #include "ascii_art_dft.hpp" //implementation -#include <boost/program_options.hpp> -#include <boost/format.hpp> +#include <uhd/usrp/multi_usrp.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <curses.h> -#include <iostream> +#include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <chrono> #include <complex> #include <cstdlib> -#include <chrono> +#include <iostream> #include <thread> namespace po = boost::program_options; using std::chrono::high_resolution_clock; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, ant, subdev, ref; size_t num_bins; double rate, freq, gain, bw, frame_rate, step; float ref_lvl, dyn_rng; bool show_controls; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -59,150 +60,176 @@ 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("rate")){ + // print the help message + if (vm.count("help") or not vm.count("rate")) { std::cout << boost::format("UHD RX ASCII Art DFT %s") % desc << std::endl; return EXIT_FAILURE; } - //create a usrp device + // create a usrp device 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); - //Lock mboard clocks + // Lock mboard clocks usrp->set_clock_source(ref); - //always select the subdevice first, the channel mapping affects the other settings - if (vm.count("subdev")) usrp->set_rx_subdev_spec(subdev); + // always select the subdevice first, the channel mapping affects the other settings + if (vm.count("subdev")) + usrp->set_rx_subdev_spec(subdev); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //set the sample rate - if (not vm.count("rate")){ + // set the sample rate + if (not vm.count("rate")) { std::cerr << "Please specify the sample rate with --rate" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_rx_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate() / 1e6) + << std::endl + << std::endl; - //set the center frequency - if (not vm.count("freq")){ + // set the center frequency + if (not vm.count("freq")) { std::cerr << "Please specify the center frequency with --freq" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; + std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq / 1e6) << std::endl; uhd::tune_request_t tune_request(freq); - if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("int-n")) + tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_rx_freq(tune_request); - std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq() / 1e6) + << std::endl + << std::endl; - //set the rf gain - if (vm.count("gain")){ + // set the rf gain + if (vm.count("gain")) { std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; usrp->set_rx_gain(gain); - std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl; + std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() + << std::endl + << std::endl; } else { gain = usrp->get_rx_gain(); } - //set the analog frontend filter bandwidth - if (vm.count("bw")){ - std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << std::endl; + // set the analog frontend filter bandwidth + if (vm.count("bw")) { + std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw / 1e6) + << std::endl; usrp->set_rx_bandwidth(bw); - std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (usrp->get_rx_bandwidth()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Bandwidth: %f MHz...") + % (usrp->get_rx_bandwidth() / 1e6) + << std::endl + << std::endl; } else { bw = usrp->get_rx_bandwidth(); } - //set the antenna - if (vm.count("ant")) usrp->set_rx_antenna(ant); + // set the antenna + if (vm.count("ant")) + usrp->set_rx_antenna(ant); - std::this_thread::sleep_for(std::chrono::seconds(1)); //allow for some setup time + std::this_thread::sleep_for(std::chrono::seconds(1)); // allow for some setup time - //Check Ref and LO Lock detect + // Check Ref and LO Lock detect std::vector<std::string> sensor_names; sensor_names = usrp->get_rx_sensor_names(0); - if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { - uhd::sensor_value_t lo_locked = usrp->get_rx_sensor("lo_locked",0); - std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() << std::endl; + if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") + != sensor_names.end()) { + uhd::sensor_value_t lo_locked = usrp->get_rx_sensor("lo_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } sensor_names = usrp->get_mboard_sensor_names(0); - if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { - uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); - std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() << std::endl; + if ((ref == "mimo") + and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") + != sensor_names.end())) { + uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (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); - std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (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); + std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } - //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); - //allocate recv buffer and metatdata + // allocate recv buffer and metatdata uhd::rx_metadata_t md; - std::vector<std::complex<float> > buff(num_bins); + std::vector<std::complex<float>> buff(num_bins); //------------------------------------------------------------------ //-- Initialize //------------------------------------------------------------------ - initscr(); //curses init + initscr(); // curses init rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); auto next_refresh = high_resolution_clock::now(); //------------------------------------------------------------------ //-- Main loop //------------------------------------------------------------------ - while (true){ - //read a buffer's worth of samples every iteration - size_t num_rx_samps = rx_stream->recv( - &buff.front(), buff.size(), md - ); - if (num_rx_samps != buff.size()) continue; - - //check and update the display refresh condition + while (true) { + // read a buffer's worth of samples every iteration + size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); + if (num_rx_samps != buff.size()) + continue; + + // check and update the display refresh condition if (high_resolution_clock::now() < next_refresh) { continue; } - next_refresh = - high_resolution_clock::now() - + std::chrono::microseconds(int64_t(1e6/frame_rate)); + next_refresh = high_resolution_clock::now() + + std::chrono::microseconds(int64_t(1e6 / frame_rate)); - //calculate the dft and create the ascii art frame + // calculate the dft and create the ascii art frame ascii_art_dft::log_pwr_dft_type lpdft( - ascii_art_dft::log_pwr_dft(&buff.front(), num_rx_samps) - ); - std::string frame = ascii_art_dft::dft_to_plot( - lpdft, COLS, (show_controls ? LINES-6 : LINES), + ascii_art_dft::log_pwr_dft(&buff.front(), num_rx_samps)); + std::string frame = ascii_art_dft::dft_to_plot(lpdft, + COLS, + (show_controls ? LINES - 6 : LINES), usrp->get_rx_rate(), usrp->get_rx_freq(), - dyn_rng, ref_lvl - ); + dyn_rng, + ref_lvl); std::string border = std::string((COLS), '-'); - //curses screen handling: clear and print frame + // curses screen handling: clear and print frame clear(); if (show_controls) { printw("%s", border.c_str()); printw("[f-F]req: %4.3f MHz | [r-R]ate: %2.2f Msps |" " [b-B]w: %2.2f MHz | [g-G]ain: %2.0f dB\n\n", - freq/1e6, rate/1e6, bw/1e6, gain); + freq / 1e6, + rate / 1e6, + bw / 1e6, + gain); printw("[d-D]yn Range: %2.0f dB | Ref [l-L]evel: %2.0f dB |" " fp[s-S] : %2.0f | [t-T]uning step: %3.3f M\n", - dyn_rng, ref_lvl, frame_rate, step/1e6); + dyn_rng, + ref_lvl, + frame_rate, + step / 1e6); printw("(press c to toggle controls)\n"); printw("%s", border.c_str()); } printw("%s", frame.c_str()); - //curses key handling: no timeout, any key to exit + // curses key handling: no timeout, any key to exit timeout(0); int ch = getch(); @@ -255,33 +282,35 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ freq = usrp->get_rx_freq(); } - else if (ch == 'l') ref_lvl -= 10; - else if (ch == 'L') ref_lvl += 10; - else if (ch == 'd') dyn_rng -= 10; - else if (ch == 'D') dyn_rng += 10; + else if (ch == 'l') + ref_lvl -= 10; + else if (ch == 'L') + ref_lvl += 10; + else if (ch == 'd') + dyn_rng -= 10; + else if (ch == 'D') + dyn_rng += 10; else if (ch == 's') { if (frame_rate > 1) { frame_rate -= 1; } - } - else if (ch == 'S') { + } else if (ch == 'S') { frame_rate += 1; - } - else if (ch == 't') { + } else if (ch == 't') { if (step > 1) { step /= 2; } - } - else if (ch == 'T') step *= 2; + } else if (ch == 'T') + step *= 2; else if (ch == 'c' || ch == 'C') { show_controls = !show_controls; } - + // Arrow keypress generates 3 characters: // '\033', '[', 'A'/'B'/'C'/'D' for Up / Down / Right / Left else if (ch == '\033') { getch(); - switch(getch()) { + switch (getch()) { case 'A': case 'C': freq += step; @@ -296,17 +325,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ freq = usrp->get_rx_freq(); break; } - } - else if (ch != KEY_RESIZE and ch != ERR) break; + } else if (ch != KEY_RESIZE and ch != ERR) + break; } //------------------------------------------------------------------ //-- Cleanup //------------------------------------------------------------------ rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - endwin(); //curses done + endwin(); // curses done - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/rx_multi_samples.cpp b/host/examples/rx_multi_samples.cpp index 8c50c5b69..f395b69b7 100644 --- a/host/examples/rx_multi_samples.cpp +++ b/host/examples/rx_multi_samples.cpp @@ -5,29 +5,30 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/algorithm/string.hpp> -#include <iostream> -#include <complex> +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <chrono> +#include <complex> +#include <iostream> #include <thread> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, sync, subdev, channel_list; double seconds_in_future; size_t total_num_samps; double rate; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -46,138 +47,145 @@ 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 RX Multi Samples %s") % desc << std::endl; - std::cout << - " This is a demonstration of how to receive aligned data from multiple channels.\n" - " This example can receive from multiple DSPs, multiple motherboards, or both.\n" - " The MIMO cable or PPS can be used to synchronize the configuration. See --sync\n" - "\n" - " Specify --subdev to select multiple channels per motherboard.\n" - " Ex: --subdev=\"0:A 0:B\" to get 2 channels on a Basic RX.\n" - "\n" - " Specify --args to select multiple motherboards in a configuration.\n" - " Ex: --args=\"addr0=192.168.10.2, addr1=192.168.10.3\"\n" - << std::endl; + std::cout + << " This is a demonstration of how to receive aligned data from multiple " + "channels.\n" + " This example can receive from multiple DSPs, multiple motherboards, " + "or both.\n" + " The MIMO cable or PPS can be used to synchronize the configuration. " + "See --sync\n" + "\n" + " Specify --subdev to select multiple channels per motherboard.\n" + " Ex: --subdev=\"0:A 0:B\" to get 2 channels on a Basic RX.\n" + "\n" + " Specify --args to select multiple motherboards in a configuration.\n" + " Ex: --args=\"addr0=192.168.10.2, addr1=192.168.10.3\"\n" + << std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; - //create a usrp device + // create a usrp device 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); - //always select the subdevice first, the channel mapping affects the other settings - if (vm.count("subdev")) usrp->set_rx_subdev_spec(subdev); //sets across all mboards + // always select the subdevice first, the channel mapping affects the other settings + if (vm.count("subdev")) + usrp->set_rx_subdev_spec(subdev); // sets across all mboards std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //set the rx sample rate (sets across all channels) - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + // set the rx sample rate (sets across all channels) + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_rx_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate() / 1e6) + << std::endl + << std::endl; std::cout << boost::format("Setting device timestamp to 0...") << std::endl; - if (sync == "now"){ - //This is not a true time lock, the devices will be off by a few RTT. - //Rather, this is just to allow for demonstration of the code below. + if (sync == "now") { + // This is not a true time lock, the devices will be off by a few RTT. + // Rather, this is just to allow for demonstration of the code below. usrp->set_time_now(uhd::time_spec_t(0.0)); - } - else if (sync == "pps"){ + } else if (sync == "pps") { usrp->set_time_source("external"); usrp->set_time_unknown_pps(uhd::time_spec_t(0.0)); - std::this_thread::sleep_for(std::chrono::seconds(1)); //wait for pps sync pulse - } - else if (sync == "mimo"){ + std::this_thread::sleep_for(std::chrono::seconds(1)); // wait for pps sync pulse + } else if (sync == "mimo") { UHD_ASSERT_THROW(usrp->get_num_mboards() == 2); - //make mboard 1 a slave over the MIMO Cable + // make mboard 1 a slave over the MIMO Cable usrp->set_clock_source("mimo", 1); usrp->set_time_source("mimo", 1); - //set time on the master (mboard 0) + // set time on the master (mboard 0) usrp->set_time_now(uhd::time_spec_t(0.0), 0); - //sleep a bit while the slave locks its time to the master + // sleep a bit while the slave locks its time to the master std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - //detect which channels to use + // detect which channels to use std::vector<std::string> channel_strings; std::vector<size_t> channel_nums; boost::split(channel_strings, channel_list, boost::is_any_of("\"',")); - for(size_t ch = 0; ch < channel_strings.size(); ch++){ + for (size_t ch = 0; ch < channel_strings.size(); ch++) { size_t chan = std::stoi(channel_strings[ch]); - if(chan >= usrp->get_rx_num_channels()){ + if (chan >= usrp->get_rx_num_channels()) { throw std::runtime_error("Invalid channel(s) specified."); - } - else channel_nums.push_back(std::stoi(channel_strings[ch])); + } else + channel_nums.push_back(std::stoi(channel_strings[ch])); } - //create a receive streamer - //linearly map channels (index0 = channel0, index1 = channel1, ...) - uhd::stream_args_t stream_args("fc32"); //complex floats - stream_args.channels = channel_nums; + // create a receive streamer + // linearly map channels (index0 = channel0, index1 = channel1, ...) + uhd::stream_args_t stream_args("fc32"); // complex floats + stream_args.channels = channel_nums; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //setup streaming + // setup streaming std::cout << std::endl; - std::cout << boost::format( - "Begin streaming %u samples, %f seconds in the future..." - ) % total_num_samps % seconds_in_future << std::endl; + std::cout << boost::format("Begin streaming %u samples, %f seconds in the future...") + % total_num_samps % seconds_in_future + << std::endl; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = total_num_samps; + stream_cmd.num_samps = total_num_samps; stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); - rx_stream->issue_stream_cmd(stream_cmd); //tells all channels to stream + stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); + rx_stream->issue_stream_cmd(stream_cmd); // tells all channels to stream - //meta-data will be filled in by recv() + // meta-data will be filled in by recv() uhd::rx_metadata_t md; - //allocate buffers to receive with samples (one buffer per channel) + // allocate buffers to receive with samples (one buffer per channel) const size_t samps_per_buff = rx_stream->get_max_num_samps(); - std::vector<std::vector<std::complex<float> > > buffs( - usrp->get_rx_num_channels(), std::vector<std::complex<float> >(samps_per_buff) - ); + std::vector<std::vector<std::complex<float>>> buffs( + usrp->get_rx_num_channels(), std::vector<std::complex<float>>(samps_per_buff)); - //create a vector of pointers to point to each of the channel buffers - std::vector<std::complex<float> *> buff_ptrs; - for (size_t i = 0; i < buffs.size(); i++) buff_ptrs.push_back(&buffs[i].front()); + // create a vector of pointers to point to each of the channel buffers + std::vector<std::complex<float>*> buff_ptrs; + for (size_t i = 0; i < buffs.size(); i++) + buff_ptrs.push_back(&buffs[i].front()); - //the first call to recv() will block this many seconds before receiving - double timeout = seconds_in_future + 0.1; //timeout (delay before receive + padding) + // the first call to recv() will block this many seconds before receiving + double timeout = seconds_in_future + 0.1; // timeout (delay before receive + padding) - size_t num_acc_samps = 0; //number of accumulated samples - while(num_acc_samps < total_num_samps){ - //receive a single packet - size_t num_rx_samps = rx_stream->recv( - buff_ptrs, samps_per_buff, md, timeout - ); + size_t num_acc_samps = 0; // number of accumulated samples + while (num_acc_samps < total_num_samps) { + // receive a single packet + size_t num_rx_samps = rx_stream->recv(buff_ptrs, samps_per_buff, md, timeout); - //use a small timeout for subsequent packets + // use a small timeout for subsequent packets timeout = 0.1; - //handle the error code - if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break; - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ - throw std::runtime_error(str(boost::format( - "Receiver error %s" - ) % md.strerror())); + // handle the error code + if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) + break; + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error( + str(boost::format("Receiver error %s") % md.strerror())); } - if(verbose) std::cout << boost::format( - "Received packet: %u samples, %u full secs, %f frac secs" - ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + if (verbose) + std::cout << boost::format( + "Received packet: %u samples, %u full secs, %f frac secs") + % num_rx_samps % md.time_spec.get_full_secs() + % md.time_spec.get_frac_secs() + << std::endl; num_acc_samps += num_rx_samps; } - if (num_acc_samps < total_num_samps) std::cerr << "Receive timeout before all samples received..." << std::endl; + if (num_acc_samps < total_num_samps) + std::cerr << "Receive timeout before all samples received..." << std::endl; - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp index c459fa257..66ec284de 100644 --- a/host/examples/rx_samples_to_file.cpp +++ b/host/examples/rx_samples_to_file.cpp @@ -5,47 +5,50 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/exception.hpp> #include <uhd/types/tune_request.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <uhd/exception.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> -#include <iostream> -#include <fstream> -#include <csignal> +#include <boost/program_options.hpp> +#include <chrono> #include <complex> +#include <csignal> +#include <fstream> +#include <iostream> #include <thread> -#include <chrono> namespace po = boost::program_options; static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} - -template<typename samp_type> void recv_to_file( - uhd::usrp::multi_usrp::sptr usrp, - const std::string &cpu_format, - const std::string &wire_format, - const size_t &channel, - const std::string &file, +void sig_int_handler(int) +{ + stop_signal_called = true; +} + +template <typename samp_type> +void recv_to_file(uhd::usrp::multi_usrp::sptr usrp, + const std::string& cpu_format, + const std::string& wire_format, + const size_t& channel, + const std::string& file, size_t samps_per_buff, unsigned long long num_requested_samples, - double time_requested = 0.0, - bool bw_summary = false, - bool stats = false, - bool null = false, - bool enable_size_map = false, - bool continue_on_bad_packet = false -){ + double time_requested = 0.0, + bool bw_summary = false, + bool stats = false, + bool null = false, + bool enable_size_map = false, + bool continue_on_bad_packet = false) +{ unsigned long long num_total_samps = 0; - //create a receive streamer - uhd::stream_args_t stream_args(cpu_format,wire_format); + // create a receive streamer + uhd::stream_args_t stream_args(cpu_format, wire_format); std::vector<size_t> channel_nums; channel_nums.push_back(channel); - stream_args.channels = channel_nums; + stream_args.channels = channel_nums; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); uhd::rx_metadata_t md; @@ -55,35 +58,30 @@ template<typename samp_type> void recv_to_file( outfile.open(file.c_str(), std::ofstream::binary); bool overflow_message = true; - //setup streaming - uhd::stream_cmd_t stream_cmd((num_requested_samples == 0)? - uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS: - uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE - ); - stream_cmd.num_samps = size_t(num_requested_samples); + // setup streaming + uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) + ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS + : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = size_t(num_requested_samples); stream_cmd.stream_now = true; - stream_cmd.time_spec = uhd::time_spec_t(); + stream_cmd.time_spec = uhd::time_spec_t(); rx_stream->issue_stream_cmd(stream_cmd); - typedef std::map<size_t,size_t> SizeMap; + typedef std::map<size_t, size_t> SizeMap; SizeMap mapSizes; const auto start_time = std::chrono::steady_clock::now(); const auto stop_time = - start_time - + std::chrono::milliseconds(int64_t(1000 * time_requested)); + start_time + std::chrono::milliseconds(int64_t(1000 * time_requested)); // Track time and samps between updating the BW summary - auto last_update = start_time; + auto last_update = start_time; unsigned long long last_update_samps = 0; // Run this loop until either time expired (if a duration was given), until // the requested number of samples were collected (if such a number was // given), or until Ctrl-C was pressed. while (not stop_signal_called - and (num_requested_samples != num_total_samps - or num_requested_samples == 0) - and (time_requested == 0.0 - or std::chrono::steady_clock::now() <= stop_time) - ) { + and (num_requested_samples != num_total_samps or num_requested_samples == 0) + and (time_requested == 0.0 or std::chrono::steady_clock::now() <= stop_time)) { const auto now = std::chrono::steady_clock::now(); size_t num_rx_samps = @@ -93,26 +91,26 @@ template<typename samp_type> void recv_to_file( std::cout << boost::format("Timeout while streaming") << std::endl; break; } - if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW){ + if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { if (overflow_message) { overflow_message = false; - std::cerr << boost::format( - "Got an overflow indication. Please consider the following:\n" - " Your write medium must sustain a rate of %fMB/s.\n" - " Dropped samples will not be written to the file.\n" - " Please modify this example for your purposes.\n" - " This message will not appear again.\n" - ) % (usrp->get_rx_rate(channel)*sizeof(samp_type)/1e6); + std::cerr + << boost::format( + "Got an overflow indication. Please consider the following:\n" + " Your write medium must sustain a rate of %fMB/s.\n" + " Dropped samples will not be written to the file.\n" + " Please modify this example for your purposes.\n" + " This message will not appear again.\n") + % (usrp->get_rx_rate(channel) * sizeof(samp_type) / 1e6); } continue; } - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::string error = str(boost::format("Receiver error: %s") % md.strerror()); - if (continue_on_bad_packet){ + if (continue_on_bad_packet) { std::cerr << error << std::endl; continue; - } - else + } else throw std::runtime_error(error); } @@ -126,10 +124,7 @@ template<typename samp_type> void recv_to_file( num_total_samps += num_rx_samps; if (outfile.is_open()) { - outfile.write( - (const char*)&buff.front(), - num_rx_samps*sizeof(samp_type) - ); + outfile.write((const char*)&buff.front(), num_rx_samps * sizeof(samp_type)); } if (bw_summary) { @@ -138,11 +133,10 @@ template<typename samp_type> void recv_to_file( if (time_since_last_update > std::chrono::seconds(1)) { const double time_since_last_update_s = std::chrono::duration<double>(time_since_last_update).count(); - const double rate = - double(last_update_samps) / time_since_last_update_s; - std::cout << "\t" << (rate/1e6) << " Msps" << std::endl; + const double rate = double(last_update_samps) / time_since_last_update_s; + std::cout << "\t" << (rate / 1e6) << " Msps" << std::endl; last_update_samps = 0; - last_update = now; + last_update = now; } } } @@ -160,13 +154,11 @@ template<typename samp_type> void recv_to_file( const double actual_duration_seconds = std::chrono::duration<float>(actual_stop_time - start_time).count(); - std::cout - << boost::format("Received %d samples in %f seconds") - % num_total_samps - % actual_duration_seconds - << std::endl; + std::cout << boost::format("Received %d samples in %f seconds") % num_total_samps + % actual_duration_seconds + << std::endl; const double rate = (double)num_total_samps / actual_duration_seconds; - std::cout << (rate/1e6) << " Msps" << std::endl; + std::cout << (rate / 1e6) << " Msps" << std::endl; if (enable_size_map) { std::cout << std::endl; @@ -179,26 +171,24 @@ template<typename samp_type> void recv_to_file( typedef std::function<uhd::sensor_value_t(const std::string&)> get_sensor_fn_t; -bool check_locked_sensor( - std::vector<std::string> sensor_names, +bool check_locked_sensor(std::vector<std::string> sensor_names, const char* sensor_name, get_sensor_fn_t get_sensor_fn, - double setup_time -) { - if (std::find(sensor_names.begin(), sensor_names.end(), sensor_name) == sensor_names.end()) + double setup_time) +{ + if (std::find(sensor_names.begin(), sensor_names.end(), sensor_name) + == sensor_names.end()) return false; - auto setup_timeout = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(int64_t(setup_time * 1000)); + auto setup_timeout = std::chrono::steady_clock::now() + + std::chrono::milliseconds(int64_t(setup_time * 1000)); bool lock_detected = false; std::cout << boost::format("Waiting for \"%s\": ") % sensor_name; std::cout.flush(); while (true) { - if (lock_detected and - (std::chrono::steady_clock::now() > setup_timeout)) { + if (lock_detected and (std::chrono::steady_clock::now() > setup_timeout)) { std::cout << " locked." << std::endl; break; } @@ -206,14 +196,13 @@ bool check_locked_sensor( std::cout << "+"; std::cout.flush(); lock_detected = true; - } - else { + } else { if (std::chrono::steady_clock::now() > setup_timeout) { std::cout << std::endl; - throw std::runtime_error(str( - boost::format("timed out waiting for consecutive locks on sensor \"%s\"") - % sensor_name - )); + throw std::runtime_error( + str(boost::format( + "timed out waiting for consecutive locks on sensor \"%s\"") + % sensor_name)); } std::cout << "_"; std::cout.flush(); @@ -224,15 +213,16 @@ bool check_locked_sensor( return true; } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, file, type, ant, subdev, ref, wirefmt; size_t channel, total_num_samps, spb; double rate, freq, gain, bw, total_time, setup_time, lo_offset; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -269,132 +259,163 @@ 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 + // print the help message if (vm.count("help")) { std::cout << boost::format("UHD RX samples to file %s") % desc << std::endl; - std::cout - << std::endl - << "This application streams data from a single channel of a USRP device to a file.\n" - << std::endl; + std::cout << std::endl + << "This application streams data from a single channel of a USRP " + "device to a file.\n" + << std::endl; return ~0; } - bool bw_summary = vm.count("progress") > 0; - bool stats = vm.count("stats") > 0; - bool null = vm.count("null") > 0; - bool enable_size_map = vm.count("sizemap") > 0; + bool bw_summary = vm.count("progress") > 0; + bool stats = vm.count("stats") > 0; + bool null = vm.count("null") > 0; + bool enable_size_map = vm.count("sizemap") > 0; bool continue_on_bad_packet = vm.count("continue") > 0; if (enable_size_map) - std::cout << "Packet size tracking enabled - will only recv one packet at a time!" << std::endl; + std::cout << "Packet size tracking enabled - will only recv one packet at a time!" + << std::endl; - //create a usrp device + // create a usrp device 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); - //Lock mboard clocks + // Lock mboard clocks usrp->set_clock_source(ref); - //always select the subdevice first, the channel mapping affects the other settings - if (vm.count("subdev")) usrp->set_rx_subdev_spec(subdev); + // always select the subdevice first, the channel mapping affects the other settings + if (vm.count("subdev")) + usrp->set_rx_subdev_spec(subdev); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //set the sample rate - if (rate <= 0.0){ + // set the sample rate + if (rate <= 0.0) { std::cerr << "Please specify a valid sample rate" << std::endl; return ~0; } - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_rx_rate(rate, channel); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate(channel)/1e6) << std::endl << std::endl; - - //set the center frequency - if (vm.count("freq")) { //with default of 0.0 this will always be true - std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; - std::cout << boost::format("Setting RX LO Offset: %f MHz...") % (lo_offset/1e6) + std::cout << boost::format("Actual RX Rate: %f Msps...") + % (usrp->get_rx_rate(channel) / 1e6) + << std::endl + << std::endl; + + // set the center frequency + if (vm.count("freq")) { // with default of 0.0 this will always be true + std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq / 1e6) + << std::endl; + std::cout << boost::format("Setting RX LO Offset: %f MHz...") % (lo_offset / 1e6) << std::endl; uhd::tune_request_t tune_request(freq, lo_offset); - if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("int-n")) + tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_rx_freq(tune_request, channel); - std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq(channel)/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Freq: %f MHz...") + % (usrp->get_rx_freq(channel) / 1e6) + << std::endl + << std::endl; } - //set the rf gain + // set the rf gain if (vm.count("gain")) { std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; usrp->set_rx_gain(gain, channel); - std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain(channel) << std::endl << std::endl; + std::cout << boost::format("Actual RX Gain: %f dB...") + % usrp->get_rx_gain(channel) + << std::endl + << std::endl; } - //set the IF filter bandwidth + // set the IF filter bandwidth if (vm.count("bw")) { - std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << std::endl; + std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw / 1e6) + << std::endl; usrp->set_rx_bandwidth(bw, channel); - std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (usrp->get_rx_bandwidth(channel)/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Bandwidth: %f MHz...") + % (usrp->get_rx_bandwidth(channel) / 1e6) + << std::endl + << std::endl; } - //set the antenna - if (vm.count("ant")) usrp->set_rx_antenna(ant, channel); + // set the antenna + if (vm.count("ant")) + usrp->set_rx_antenna(ant, channel); - std::this_thread::sleep_for( - std::chrono::milliseconds(int64_t(1000 * setup_time)) - ); + std::this_thread::sleep_for(std::chrono::milliseconds(int64_t(1000 * setup_time))); - //check Ref and LO Lock detect - if (not vm.count("skip-lo")){ - check_locked_sensor( - usrp->get_rx_sensor_names(channel), + // check Ref and LO Lock detect + if (not vm.count("skip-lo")) { + check_locked_sensor(usrp->get_rx_sensor_names(channel), "lo_locked", - [usrp,channel](const std::string& sensor_name){ + [usrp, channel](const std::string& sensor_name) { return usrp->get_rx_sensor(sensor_name, channel); }, - setup_time - ); + setup_time); if (ref == "mimo") { - check_locked_sensor( - usrp->get_mboard_sensor_names(0), + check_locked_sensor(usrp->get_mboard_sensor_names(0), "mimo_locked", - [usrp](const std::string& sensor_name){ + [usrp](const std::string& sensor_name) { return usrp->get_mboard_sensor(sensor_name); }, - setup_time - ); + setup_time); } if (ref == "external") { - check_locked_sensor( - usrp->get_mboard_sensor_names(0), + check_locked_sensor(usrp->get_mboard_sensor_names(0), "ref_locked", - [usrp](const std::string& sensor_name){ + [usrp](const std::string& sensor_name) { return usrp->get_mboard_sensor(sensor_name); }, - setup_time - ); + setup_time); } } - if (total_num_samps == 0){ + if (total_num_samps == 0) { std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; } #define recv_to_file_args(format) \ - (usrp, format, wirefmt, channel, file, spb, total_num_samps, total_time, bw_summary, stats, null, enable_size_map, continue_on_bad_packet) - //recv to file + (usrp, \ + format, \ + wirefmt, \ + channel, \ + file, \ + spb, \ + total_num_samps, \ + total_time, \ + bw_summary, \ + stats, \ + null, \ + enable_size_map, \ + continue_on_bad_packet) + // recv to file if (wirefmt == "s16") { - if (type == "double") recv_to_file<double>recv_to_file_args("f64"); - else if (type == "float") recv_to_file<float>recv_to_file_args("f32"); - else if (type == "short") recv_to_file<short>recv_to_file_args("s16"); - else throw std::runtime_error("Unknown type " + type); + if (type == "double") + recv_to_file<double> recv_to_file_args("f64"); + else if (type == "float") + recv_to_file<float> recv_to_file_args("f32"); + else if (type == "short") + recv_to_file<short> recv_to_file_args("s16"); + else + throw std::runtime_error("Unknown type " + type); } else { - if (type == "double") recv_to_file<std::complex<double> >recv_to_file_args("fc64"); - else if (type == "float") recv_to_file<std::complex<float> >recv_to_file_args("fc32"); - else if (type == "short") recv_to_file<std::complex<short> >recv_to_file_args("sc16"); - else throw std::runtime_error("Unknown type " + type); + if (type == "double") + recv_to_file<std::complex<double>> recv_to_file_args("fc64"); + else if (type == "float") + recv_to_file<std::complex<float>> recv_to_file_args("fc32"); + else if (type == "short") + recv_to_file<std::complex<short>> recv_to_file_args("sc16"); + else + throw std::runtime_error("Unknown type " + type); } - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp index 5268de020..6dd04ec6a 100644 --- a/host/examples/rx_samples_to_udp.cpp +++ b/host/examples/rx_samples_to_udp.cpp @@ -5,31 +5,32 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/exception.hpp> +#include <uhd/transport/udp_simple.hpp> #include <uhd/types/tune_request.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <uhd/transport/udp_simple.hpp> -#include <uhd/exception.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> -#include <complex> +#include <boost/program_options.hpp> #include <chrono> +#include <complex> +#include <iostream> #include <thread> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, file, ant, subdev, ref; size_t total_num_samps; double rate, freq, gain, bw; std::string addr, port; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -52,122 +53,144 @@ 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 RX to UDP %s") % desc << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //Lock mboard clocks + // Lock mboard clocks usrp->set_clock_source(ref); - //always select the subdevice first, the channel mapping affects the other settings + // always select the subdevice first, the channel mapping affects the other settings if (vm.count("subdev")) { usrp->set_rx_subdev_spec(subdev); } - //set the rx sample rate - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + // set the rx sample rate + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_rx_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate() / 1e6) + << std::endl + << std::endl; - //set the rx center frequency - std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; + // set the rx center frequency + std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq / 1e6) << std::endl; uhd::tune_request_t tune_request(freq); - if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("int-n")) + tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_rx_freq(tune_request); - std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq() / 1e6) + << std::endl + << std::endl; - //set the rx rf gain + // set the rx rf gain std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; usrp->set_rx_gain(gain); - std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl; - - //set the analog frontend filter bandwidth - if (vm.count("bw")){ - std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << std::endl; + std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() + << std::endl + << std::endl; + + // set the analog frontend filter bandwidth + if (vm.count("bw")) { + std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw / 1e6) + << std::endl; usrp->set_rx_bandwidth(bw); - std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (usrp->get_rx_bandwidth()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Bandwidth: %f MHz...") + % (usrp->get_rx_bandwidth() / 1e6) + << std::endl + << std::endl; } - //set the antenna - if (vm.count("ant")) usrp->set_rx_antenna(ant); + // set the antenna + if (vm.count("ant")) + usrp->set_rx_antenna(ant); - std::this_thread::sleep_for(std::chrono::seconds(1)); //allow for some setup time + std::this_thread::sleep_for(std::chrono::seconds(1)); // allow for some setup time - //Check Ref and LO Lock detect + // Check Ref and LO Lock detect std::vector<std::string> sensor_names; sensor_names = usrp->get_rx_sensor_names(0); - if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { - uhd::sensor_value_t lo_locked = usrp->get_rx_sensor("lo_locked",0); - std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() << std::endl; + if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") + != sensor_names.end()) { + uhd::sensor_value_t lo_locked = usrp->get_rx_sensor("lo_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } sensor_names = usrp->get_mboard_sensor_names(0); - if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { - uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); - std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() << std::endl; + if ((ref == "mimo") + and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") + != sensor_names.end())) { + uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (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); - std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (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); + std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } - //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); - //setup streaming + // setup streaming uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = total_num_samps; + stream_cmd.num_samps = total_num_samps; stream_cmd.stream_now = true; rx_stream->issue_stream_cmd(stream_cmd); - //loop until total number of samples reached - size_t num_acc_samps = 0; //number of accumulated samples + // loop until total number of samples reached + size_t num_acc_samps = 0; // number of accumulated samples uhd::rx_metadata_t md; - std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); - uhd::transport::udp_simple::sptr udp_xport = uhd::transport::udp_simple::make_connected(addr, port); - - while(num_acc_samps < total_num_samps){ - size_t num_rx_samps = rx_stream->recv( - &buff.front(), buff.size(), md - ); - - //handle the error codes - switch(md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - break; - - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - if (num_acc_samps == 0) continue; - std::cout << boost::format( - "Got timeout before all samples received, possible packet loss, exiting loop..." - ) << std::endl; - goto done_loop; - - default: - std::cout << boost::format( - "Got error code 0x%x, exiting loop..." - ) % md.error_code << std::endl; - goto done_loop; + std::vector<std::complex<float>> buff(rx_stream->get_max_num_samps()); + uhd::transport::udp_simple::sptr udp_xport = + uhd::transport::udp_simple::make_connected(addr, port); + + while (num_acc_samps < total_num_samps) { + size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); + + // handle the error codes + switch (md.error_code) { + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) + continue; + std::cout << boost::format("Got timeout before all samples received, " + "possible packet loss, exiting loop...") + << std::endl; + goto done_loop; + + default: + std::cout << boost::format("Got error code 0x%x, exiting loop...") + % md.error_code + << std::endl; + goto done_loop; } - //send complex single precision floating point samples over udp - udp_xport->send(boost::asio::buffer(buff, num_rx_samps*sizeof(buff.front()))); + // send complex single precision floating point samples over udp + udp_xport->send(boost::asio::buffer(buff, num_rx_samps * sizeof(buff.front()))); num_acc_samps += num_rx_samps; - } done_loop: + } +done_loop: - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index cfe710409..6411cb4cc 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -5,21 +5,22 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/algorithm/string.hpp> -#include <iostream> +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <complex> +#include <iostream> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; std::string wire; double seconds_in_future; @@ -27,7 +28,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ double rate; std::string channel_list; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -45,96 +46,101 @@ 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 RX Timed Samples %s") % desc << std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //detect which channels to use + // detect which channels to use std::vector<std::string> channel_strings; std::vector<size_t> channel_nums; boost::split(channel_strings, channel_list, boost::is_any_of("\"',")); - for(size_t ch = 0; ch < channel_strings.size(); ch++){ + for (size_t ch = 0; ch < channel_strings.size(); ch++) { size_t chan = std::stoi(channel_strings[ch]); - if(chan >= usrp->get_tx_num_channels() or chan >= usrp->get_rx_num_channels()){ + if (chan >= usrp->get_tx_num_channels() or chan >= usrp->get_rx_num_channels()) { throw std::runtime_error("Invalid channel(s) specified."); - } - else channel_nums.push_back(std::stoi(channel_strings[ch])); + } else + channel_nums.push_back(std::stoi(channel_strings[ch])); } - //set the rx sample rate - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + // set the rx sample rate + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_rx_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate() / 1e6) + << std::endl + << std::endl; std::cout << boost::format("Setting device timestamp to 0...") << std::endl; usrp->set_time_now(uhd::time_spec_t(0.0)); - //create a receive streamer - uhd::stream_args_t stream_args("fc32", wire); //complex floats - stream_args.channels = channel_nums; + // create a receive streamer + uhd::stream_args_t stream_args("fc32", wire); // complex floats + stream_args.channels = channel_nums; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //setup streaming + // setup streaming std::cout << std::endl; - std::cout << boost::format( - "Begin streaming %u samples, %f seconds in the future..." - ) % total_num_samps % seconds_in_future << std::endl; + std::cout << boost::format("Begin streaming %u samples, %f seconds in the future...") + % total_num_samps % seconds_in_future + << std::endl; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = total_num_samps; + stream_cmd.num_samps = total_num_samps; stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); + stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); rx_stream->issue_stream_cmd(stream_cmd); - //meta-data will be filled in by recv() + // meta-data will be filled in by recv() uhd::rx_metadata_t md; - //allocate buffer to receive with samples - std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); - std::vector<void *> buffs; + // allocate buffer to receive with samples + std::vector<std::complex<float>> buff(rx_stream->get_max_num_samps()); + std::vector<void*> buffs; for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) - buffs.push_back(&buff.front()); //same buffer for each channel + buffs.push_back(&buff.front()); // same buffer for each channel - //the first call to recv() will block this many seconds before receiving - double timeout = seconds_in_future + 0.1; //timeout (delay before receive + padding) + // the first call to recv() will block this many seconds before receiving + double timeout = seconds_in_future + 0.1; // timeout (delay before receive + padding) - size_t num_acc_samps = 0; //number of accumulated samples - while(num_acc_samps < total_num_samps){ - //receive a single packet - size_t num_rx_samps = rx_stream->recv( - buffs, buff.size(), md, timeout, true - ); + size_t num_acc_samps = 0; // number of accumulated samples + while (num_acc_samps < total_num_samps) { + // receive a single packet + size_t num_rx_samps = rx_stream->recv(buffs, buff.size(), md, timeout, true); - //use a small timeout for subsequent packets + // use a small timeout for subsequent packets timeout = 0.1; - //handle the error code - if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break; - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ - throw std::runtime_error(str(boost::format( - "Receiver error %s" - ) % md.strerror())); + // handle the error code + if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) + break; + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error( + str(boost::format("Receiver error %s") % md.strerror())); } - if(verbose) std::cout << boost::format( - "Received packet: %u samples, %u full secs, %f frac secs" - ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + if (verbose) + std::cout << boost::format( + "Received packet: %u samples, %u full secs, %f frac secs") + % num_rx_samps % md.time_spec.get_full_secs() + % md.time_spec.get_frac_secs() + << std::endl; num_acc_samps += num_rx_samps; } - if (num_acc_samps < total_num_samps) std::cerr << "Receive timeout before all samples received..." << std::endl; + if (num_acc_samps < total_num_samps) + std::cerr << "Receive timeout before all samples received..." << std::endl; - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/sync_to_gps.cpp b/host/examples/sync_to_gps.cpp index 3449aef55..952e7f8b3 100644 --- a/host/examples/sync_to_gps.cpp +++ b/host/examples/sync_to_gps.cpp @@ -4,13 +4,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> #include <boost/program_options.hpp> -#include <iostream> #include <chrono> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -18,20 +18,28 @@ namespace po = boost::program_options; 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("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n"); - std::cout << boost::format("****************************************************************************************************************\n"); + std::cout << boost::format( + "**************************************Helpful Notes on Clock/PPS " + "Selection**************************************\n"); + std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS " + "signals are now from the GPSDO.\n"); + std::cout << boost::format( + "If you would like to use the internal reference(TCXO) in other applications, " + "you must configure that explicitly.\n"); + std::cout << boost::format( + "You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n"); + std::cout << boost::format( + "********************************************************************************" + "********************************\n"); } -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { uhd::set_thread_priority_safe(); std::string args; - //Set up program options + // Set up program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -43,27 +51,25 @@ 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("Synchronize USRP to GPS %s") % desc << std::endl; return EXIT_FAILURE; } - //Create a USRP device + // 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(); - try - { - size_t num_mboards = usrp->get_num_mboards(); + try { + size_t num_mboards = usrp->get_num_mboards(); size_t num_gps_locked = 0; - for (size_t mboard = 0; mboard < num_mboards; mboard++) - { - std::cout << "Synchronizing mboard " << mboard << ": " << usrp->get_mboard_name(mboard) << std::endl; + for (size_t mboard = 0; mboard < num_mboards; mboard++) { + std::cout << "Synchronizing mboard " << mboard << ": " + << usrp->get_mboard_name(mboard) << std::endl; - //Set references to GPSDO + // Set references to GPSDO usrp->set_clock_source("gpsdo", mboard); usrp->set_time_source("gpsdo", mboard); @@ -71,112 +77,117 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) print_notes(); std::cout << std::endl; - //Check for 10 MHz lock + // Check for 10 MHz lock std::vector<std::string> sensor_names = usrp->get_mboard_sensor_names(mboard); - if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) - { + if (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") + != sensor_names.end()) { std::cout << "Waiting for reference lock..." << std::flush; bool ref_locked = false; - for (int i = 0; i < 30 and not ref_locked; i++) - { + for (int i = 0; i < 30 and not ref_locked; i++) { ref_locked = usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); - if (not ref_locked) - { + if (not ref_locked) { std::cout << "." << std::flush; std::this_thread::sleep_for(std::chrono::seconds(1)); } } - if(ref_locked) - { + if (ref_locked) { std::cout << "LOCKED" << std::endl; } else { std::cout << "FAILED" << std::endl; - std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; + std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." + << std::endl; exit(EXIT_FAILURE); } - } - else - { - std::cout << boost::format("ref_locked sensor not present on this board.\n"); + } else { + std::cout << boost::format( + "ref_locked sensor not present on this board.\n"); } - //Wait for GPS lock + // Wait for GPS lock bool gps_locked = usrp->get_mboard_sensor("gps_locked", mboard).to_bool(); - if(gps_locked) - { + if (gps_locked) { num_gps_locked++; std::cout << boost::format("GPS Locked\n"); - } - else - { - std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl; + } else { + std::cerr + << "WARNING: GPS not locked - time will not be accurate until locked" + << std::endl; } - //Set to GPS time - uhd::time_spec_t gps_time = uhd::time_spec_t(int64_t(usrp->get_mboard_sensor("gps_time", mboard).to_int())); - usrp->set_time_next_pps(gps_time+1.0, mboard); + // Set to GPS time + uhd::time_spec_t gps_time = uhd::time_spec_t( + int64_t(usrp->get_mboard_sensor("gps_time", mboard).to_int())); + usrp->set_time_next_pps(gps_time + 1.0, mboard); - //Wait for it to apply - //The wait is 2 seconds because N-Series has a known issue where - //the time at the last PPS does not properly update at the PPS edge - //when the time is actually set. + // Wait for it to apply + // The wait is 2 seconds because N-Series has a known issue where + // the time at the last PPS does not properly update at the PPS edge + // when the time is actually set. std::this_thread::sleep_for(std::chrono::seconds(2)); - //Check times - gps_time = uhd::time_spec_t(int64_t(usrp->get_mboard_sensor("gps_time", mboard).to_int())); + // Check times + gps_time = uhd::time_spec_t( + int64_t(usrp->get_mboard_sensor("gps_time", mboard).to_int())); uhd::time_spec_t time_last_pps = usrp->get_time_last_pps(mboard); - std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl; - std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; + std::cout << "USRP time: " + << (boost::format("%0.9f") % time_last_pps.get_real_secs()) + << std::endl; + std::cout << "GPSDO time: " + << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) - std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; + std::cout << std::endl + << "SUCCESS: USRP time synchronized to GPS time" << std::endl + << std::endl; else - std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; + std::cerr << std::endl + << "ERROR: Failed to synchronize USRP time to GPS time" + << std::endl + << std::endl; } - if (num_gps_locked == num_mboards and num_mboards > 1) - { - //Check to see if all USRP times are aligned - //First, wait for PPS. + if (num_gps_locked == num_mboards and num_mboards > 1) { + // Check to see if all USRP times are aligned + // First, wait for PPS. uhd::time_spec_t time_last_pps = usrp->get_time_last_pps(); - while (time_last_pps == usrp->get_time_last_pps()) - { + while (time_last_pps == usrp->get_time_last_pps()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - //Sleep a little to make sure all devices have seen a PPS edge + // Sleep a little to make sure all devices have seen a PPS edge std::this_thread::sleep_for(std::chrono::milliseconds(200)); - //Compare times across all mboards - bool all_matched = true; + // Compare times across all mboards + bool all_matched = true; uhd::time_spec_t mboard0_time = usrp->get_time_last_pps(0); - for (size_t mboard = 1; mboard < num_mboards; mboard++) - { + for (size_t mboard = 1; mboard < num_mboards; mboard++) { uhd::time_spec_t mboard_time = usrp->get_time_last_pps(mboard); - if (mboard_time != mboard0_time) - { + if (mboard_time != mboard0_time) { all_matched = false; - std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f") - % mboard0_time.get_real_secs() - % mboard - % mboard_time.get_real_secs()) << std::endl; + std::cerr << (boost::format("ERROR: Times are not aligned: USRP " + "0=%0.9f, USRP %d=%0.9f") + % mboard0_time.get_real_secs() % mboard + % mboard_time.get_real_secs()) + << std::endl; } } - if (all_matched) - { + if (all_matched) { std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl; } else { - std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl; + std::cout << "ERROR: USRP times are not aligned" << std::endl + << std::endl; } } - } - catch (std::exception& e) - { + } catch (std::exception& e) { std::cout << boost::format("\nError: %s") % e.what(); - std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n"); + std::cout << boost::format( + "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"); - std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); - std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); + std::cout << boost::format( + " * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"); + std::cout << boost::format( + " * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); + std::cout << boost::format( + " * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); exit(EXIT_FAILURE); } diff --git a/host/examples/test_clock_synch.cpp b/host/examples/test_clock_synch.cpp index cb34e625c..96ebd05a6 100644 --- a/host/examples/test_clock_synch.cpp +++ b/host/examples/test_clock_synch.cpp @@ -7,17 +7,15 @@ #include <uhd/device.hpp> #include <uhd/exception.hpp> -#include <uhd/usrp_clock/multi_usrp_clock.hpp> #include <uhd/types/time_spec.hpp> #include <uhd/usrp/multi_usrp.hpp> +#include <uhd/usrp_clock/multi_usrp_clock.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/utils/thread.hpp> - #include <boost/format.hpp> #include <boost/program_options.hpp> - -#include <iostream> #include <chrono> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -25,18 +23,20 @@ namespace po = boost::program_options; using namespace uhd::usrp_clock; using namespace uhd::usrp; -void get_usrp_time(multi_usrp::sptr usrp, size_t mboard, std::vector<int64_t> *times){ +void get_usrp_time(multi_usrp::sptr usrp, size_t mboard, std::vector<int64_t>* times) +{ (*times)[mboard] = usrp->get_time_now(mboard).get_full_secs(); } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //Variables to be set by command line options + // Variables to be set by command line options std::string clock_args, usrp_args; uint32_t max_interval, num_tests; - //Set up program options + // Set up program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -51,83 +51,96 @@ 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 << std::endl << "Test Clock Synchronization" << std::endl << std::endl; std::cout << "This example shows how to use a clock device to" << std::endl - << "synchronize the time on multiple USRP devices." << std::endl << std::endl; + << "synchronize the time on multiple USRP devices." << std::endl + << std::endl; std::cout << desc << std::endl; return EXIT_SUCCESS; } - //Create a Multi-USRP-Clock device (currently OctoClock only) - std::cout << boost::format("\nCreating the Clock device with: %s") % clock_args << std::endl; + // Create a Multi-USRP-Clock device (currently OctoClock only) + std::cout << boost::format("\nCreating the Clock device with: %s") % clock_args + << std::endl; multi_usrp_clock::sptr clock = multi_usrp_clock::make(clock_args); - //Make sure Clock configuration is correct - if(clock->get_sensor("gps_detected").value == "false"){ + // Make sure Clock configuration is correct + if (clock->get_sensor("gps_detected").value == "false") { throw uhd::runtime_error("No GPSDO detected on Clock."); } - if(clock->get_sensor("using_ref").value != "internal"){ + if (clock->get_sensor("using_ref").value != "internal") { throw uhd::runtime_error("Clock must be using an internal reference."); } - //Create a Multi-USRP device - std::cout << boost::format("\nCreating the USRP device with: %s") % usrp_args << std::endl; + // Create a Multi-USRP device + std::cout << boost::format("\nCreating the USRP device with: %s") % usrp_args + << std::endl; multi_usrp::sptr usrp = multi_usrp::make(usrp_args); - //Store USRP device serials for useful output + // Store USRP device serials for useful output std::vector<std::string> serials; - for(size_t ch = 0; ch < usrp->get_num_mboards(); ch++){ + for (size_t ch = 0; ch < usrp->get_num_mboards(); ch++) { serials.push_back(usrp->get_usrp_tx_info(ch)["mboard_serial"]); } std::cout << std::endl << "Checking USRP devices for lock." << std::endl; bool all_locked = true; - for(size_t ch = 0; ch < usrp->get_num_mboards(); ch++){ - std::string ref_locked = usrp->get_mboard_sensor("ref_locked",ch).value; + for (size_t ch = 0; ch < usrp->get_num_mboards(); ch++) { + std::string ref_locked = usrp->get_mboard_sensor("ref_locked", ch).value; std::cout << boost::format(" * %s: %s") % serials[ch] % ref_locked << std::endl; - if(ref_locked != "true") all_locked = false; + if (ref_locked != "true") + all_locked = false; } - if(not all_locked) std::cout << std::endl << "WARNING: One or more devices not locked." << std::endl; + if (not all_locked) + std::cout << std::endl << "WARNING: One or more devices not locked." << std::endl; - //Get GPS time to initially set USRP devices - std::cout << std::endl << "Querying Clock for time and setting USRP times..." << std::endl << std::endl; + // Get GPS time to initially set USRP devices + std::cout << std::endl + << "Querying Clock for time and setting USRP times..." << std::endl + << std::endl; int64_t clock_time = clock->get_time(); - usrp->set_time_next_pps(uhd::time_spec_t(double(clock_time+1))); + usrp->set_time_next_pps(uhd::time_spec_t(double(clock_time + 1))); srand((unsigned int)time(NULL)); - std::cout << boost::format("Running %d comparisons at random intervals.") % num_tests << std::endl; + std::cout << boost::format("Running %d comparisons at random intervals.") % num_tests + << std::endl; uint32_t num_matches = 0; - for(size_t i = 0; i < num_tests; i++){ - //Wait random time before querying + for (size_t i = 0; i < num_tests; i++) { + // Wait random time before querying uint16_t wait_time = rand() % max_interval; std::this_thread::sleep_for(std::chrono::milliseconds(wait_time)); - //Get all times before output + // Get all times before output std::vector<int64_t> usrp_times(usrp->get_num_mboards()); boost::thread_group thread_group; clock_time = clock->get_time(); - for(size_t j = 0; j < usrp->get_num_mboards(); j++){ + for (size_t j = 0; j < usrp->get_num_mboards(); j++) { thread_group.create_thread(boost::bind(&get_usrp_time, usrp, j, &usrp_times)); } - //Wait for threads to complete + // Wait for threads to complete thread_group.join_all(); - std::cout << boost::format("Comparison #%d") % (i+1) << std::endl; + std::cout << boost::format("Comparison #%d") % (i + 1) << std::endl; bool all_match = true; std::cout << boost::format(" * Clock time: %d") % clock_time << std::endl; - for(size_t j = 0; j < usrp->get_num_mboards(); j++){ - std::cout << boost::format(" * %s time: %d") % serials[j] % usrp_times[j] << std::endl; - if(usrp_times[j] != clock_time) all_match = false; + for (size_t j = 0; j < usrp->get_num_mboards(); j++) { + std::cout << boost::format(" * %s time: %d") % serials[j] % usrp_times[j] + << std::endl; + if (usrp_times[j] != clock_time) + all_match = false; } - if(all_match) num_matches++; + if (all_match) + num_matches++; } - std::cout << std::endl << boost::format("Number of matches: %d/%d") % num_matches % num_tests << std::endl; + std::cout << std::endl + << boost::format("Number of matches: %d/%d") % num_matches % num_tests + << std::endl; return EXIT_SUCCESS; } diff --git a/host/examples/test_dboard_coercion.cpp b/host/examples/test_dboard_coercion.cpp index 1bbe6a81b..8ea2446fa 100644 --- a/host/examples/test_dboard_coercion.cpp +++ b/host/examples/test_dboard_coercion.cpp @@ -5,35 +5,38 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> #include <boost/math/special_functions/round.hpp> -#include <iostream> +#include <boost/program_options.hpp> +#include <chrono> #include <complex> +#include <iostream> +#include <thread> #include <utility> #include <vector> -#include <chrono> -#include <thread> static const double SAMP_RATE = 1e6; namespace po = boost::program_options; -typedef std::pair<double, double> double_pair; //BOOST_FOREACH doesn't like commas -typedef std::vector<std::pair<double, double> > pair_vector; +typedef std::pair<double, double> double_pair; // BOOST_FOREACH doesn't like commas +typedef std::vector<std::pair<double, double>> pair_vector; /************************************************************************ * Misc functions -************************************************************************/ + ************************************************************************/ -std::string MHz_str(double freq){ +std::string MHz_str(double freq) +{ return std::string(str(boost::format("%5.2f MHz") % (freq / 1e6))); } -std::string return_usrp_config_string(uhd::usrp::multi_usrp::sptr usrp, int chan, bool test_tx, bool test_rx, bool is_b2xx){ +std::string return_usrp_config_string( + uhd::usrp::multi_usrp::sptr usrp, int chan, bool test_tx, bool test_rx, bool is_b2xx) +{ uhd::dict<std::string, std::string> tx_info = usrp->get_usrp_tx_info(chan); uhd::dict<std::string, std::string> rx_info = usrp->get_usrp_rx_info(chan); std::string info_string; @@ -42,195 +45,236 @@ std::string return_usrp_config_string(uhd::usrp::multi_usrp::sptr usrp, int chan std::string rx_serial, rx_subdev_name, rx_subdev_spec; mboard_id = tx_info.get("mboard_id"); - if(tx_info.get("mboard_serial") == "") mboard_serial = "no serial"; - else mboard_serial = tx_info.get("mboard_serial"); - - info_string = str(boost::format("Motherboard: %s (%s)\n") % mboard_id % mboard_serial); - - if(test_tx){ - if(tx_info.get("tx_serial") == "") tx_serial = "no serial"; - else tx_serial = tx_info.get("tx_serial"); + if (tx_info.get("mboard_serial") == "") + mboard_serial = "no serial"; + else + mboard_serial = tx_info.get("mboard_serial"); + + info_string = + str(boost::format("Motherboard: %s (%s)\n") % mboard_id % mboard_serial); + + if (test_tx) { + if (tx_info.get("tx_serial") == "") + tx_serial = "no serial"; + else + tx_serial = tx_info.get("tx_serial"); tx_subdev_name = tx_info.get("tx_subdev_name"); tx_subdev_spec = tx_info.get("tx_subdev_spec"); - info_string += is_b2xx ? str(boost::format("TX: %s (%s)") - % tx_subdev_name % tx_subdev_spec) - : str(boost::format("TX: %s (%s, %s)") - % tx_subdev_name % tx_serial % tx_subdev_spec); + info_string += + is_b2xx ? str(boost::format("TX: %s (%s)") % tx_subdev_name % tx_subdev_spec) + : str(boost::format("TX: %s (%s, %s)") % tx_subdev_name % tx_serial + % tx_subdev_spec); } - if(test_tx and test_rx) info_string += "\n"; - if(test_rx){ - if(rx_info.get("rx_serial") == "") rx_serial = "no serial"; - else rx_serial = rx_info.get("rx_serial"); + if (test_tx and test_rx) + info_string += "\n"; + if (test_rx) { + if (rx_info.get("rx_serial") == "") + rx_serial = "no serial"; + else + rx_serial = rx_info.get("rx_serial"); rx_subdev_name = rx_info.get("rx_subdev_name"); rx_subdev_spec = rx_info.get("rx_subdev_spec"); - info_string += is_b2xx ? str(boost::format("RX: %s (%s)") - % rx_subdev_name % rx_subdev_spec) - : str(boost::format("RX: %s (%s, %s)") - % rx_subdev_name % rx_serial % rx_subdev_spec); + info_string += + is_b2xx ? str(boost::format("RX: %s (%s)") % rx_subdev_name % rx_subdev_spec) + : str(boost::format("RX: %s (%s, %s)") % rx_subdev_name % rx_serial + % rx_subdev_spec); } return info_string; } -std::string coercion_test(uhd::usrp::multi_usrp::sptr usrp, std::string type, int chan, - bool test_gain, double freq_step, double gain_step, bool verbose){ - - //Getting USRP info - uhd::dict<std::string, std::string> usrp_info = (type == "TX") ? usrp->get_usrp_tx_info(chan) - : usrp->get_usrp_rx_info(chan); +std::string coercion_test(uhd::usrp::multi_usrp::sptr usrp, + std::string type, + int chan, + bool test_gain, + double freq_step, + double gain_step, + bool verbose) +{ + // Getting USRP info + uhd::dict<std::string, std::string> usrp_info = + (type == "TX") ? usrp->get_usrp_tx_info(chan) : usrp->get_usrp_rx_info(chan); std::string subdev_name = (type == "TX") ? usrp_info.get("tx_subdev_name") : usrp_info.get("rx_subdev_name"); std::string subdev_spec = (type == "TX") ? usrp_info.get("tx_subdev_spec") : usrp_info.get("rx_subdev_spec"); - //Establish frequency range + // Establish frequency range std::vector<double> freqs; - std::vector<double> xcvr_freqs; //XCVR2450 has two ranges - uhd::freq_range_t freq_ranges = (type == "TX") ? usrp->get_fe_tx_freq_range(chan) - : usrp->get_fe_rx_freq_range(chan); + std::vector<double> xcvr_freqs; // XCVR2450 has two ranges + uhd::freq_range_t freq_ranges = (type == "TX") ? usrp->get_fe_tx_freq_range(chan) + : usrp->get_fe_rx_freq_range(chan); std::cout << boost::format("\nTesting %s coercion...") % type << std::endl; - for(const uhd::range_t &range: freq_ranges){ + for (const uhd::range_t& range : freq_ranges) { double freq_begin = range.start(); - double freq_end = range.stop(); + double freq_end = range.stop(); - if(subdev_name.find("XCVR2450") == 0){ + if (subdev_name.find("XCVR2450") == 0) { xcvr_freqs.push_back(freq_begin); xcvr_freqs.push_back(freq_end); } double current_freq = freq_begin; - while(current_freq < freq_end){ + while (current_freq < freq_end) { freqs.push_back(current_freq); current_freq += freq_step; } - if(freq_end != *freqs.end()) freqs.push_back(freq_end); + if (freq_end != *freqs.end()) + freqs.push_back(freq_end); } std::vector<double> gains; - if(test_gain){ - //Establish gain range + if (test_gain) { + // Establish gain range uhd::gain_range_t gain_range = (type == "TX") ? usrp->get_tx_gain_range(chan) : usrp->get_rx_gain_range(chan); double gain_begin = gain_range.start(); - //Start gain at 0 if range begins negative - if(gain_begin < 0.0) gain_begin = 0.0; + // Start gain at 0 if range begins negative + if (gain_begin < 0.0) + gain_begin = 0.0; double gain_end = gain_range.stop(); double current_gain = gain_begin; - while(current_gain < gain_end){ + while (current_gain < gain_end) { gains.push_back(current_gain); current_gain += gain_step; } gains.push_back(gain_end); } - //Establish error-storing variables + // Establish error-storing variables std::vector<double> bad_tune_freqs; std::vector<double> no_lock_freqs; pair_vector bad_gain_vals; - //Sensor names - std::vector<std::string> dboard_sensor_names = (type == "TX") ? usrp->get_tx_sensor_names(chan) - : usrp->get_rx_sensor_names(chan); + // Sensor names + std::vector<std::string> dboard_sensor_names = (type == "TX") + ? usrp->get_tx_sensor_names(chan) + : usrp->get_rx_sensor_names(chan); std::vector<std::string> mboard_sensor_names = usrp->get_mboard_sensor_names(); - bool has_sensor = (std::find(dboard_sensor_names.begin(), dboard_sensor_names.end(), "lo_locked")) != dboard_sensor_names.end(); - - for(double freq: freqs){ + bool has_sensor = + (std::find(dboard_sensor_names.begin(), dboard_sensor_names.end(), "lo_locked")) + != dboard_sensor_names.end(); - //Testing for successful frequency tune - if(type == "TX") usrp->set_tx_freq(freq,chan); - else usrp->set_rx_freq(freq,chan); + for (double freq : freqs) { + // Testing for successful frequency tune + if (type == "TX") + usrp->set_tx_freq(freq, chan); + else + usrp->set_rx_freq(freq, chan); std::this_thread::sleep_for(std::chrono::microseconds(long(1000))); double actual_freq = (type == "TX") ? usrp->get_tx_freq(chan) : usrp->get_rx_freq(chan); - if(freq == 0.0){ - if(floor(actual_freq + 0.5) == 0.0){ - if(verbose) std::cout << boost::format("\n%s frequency successfully tuned to %s.") - % type % MHz_str(freq) << std::endl; - } - else{ - if(verbose) std::cout << boost::format("\n%s frequency tuned to %s instead of %s.") - % type % MHz_str(actual_freq) % MHz_str(freq) << std::endl; + if (freq == 0.0) { + if (floor(actual_freq + 0.5) == 0.0) { + if (verbose) + std::cout << boost::format("\n%s frequency successfully tuned to %s.") + % type % MHz_str(freq) + << std::endl; + } else { + if (verbose) + std::cout << boost::format( + "\n%s frequency tuned to %s instead of %s.") + % type % MHz_str(actual_freq) % MHz_str(freq) + << std::endl; bad_tune_freqs.push_back(freq); } - } - else{ - if((freq / actual_freq > 0.9999) and (freq / actual_freq < 1.0001)){ - if(verbose) std::cout << boost::format("\n%s frequency successfully tuned to %s.") - % type % MHz_str(freq) << std::endl; - } - else{ - if(verbose) std::cout << boost::format("\n%s frequency tuned to %s instead of %s.") - % type % MHz_str(actual_freq) % MHz_str(freq) << std::endl; + } else { + if ((freq / actual_freq > 0.9999) and (freq / actual_freq < 1.0001)) { + if (verbose) + std::cout << boost::format("\n%s frequency successfully tuned to %s.") + % type % MHz_str(freq) + << std::endl; + } else { + if (verbose) + std::cout << boost::format( + "\n%s frequency tuned to %s instead of %s.") + % type % MHz_str(actual_freq) % MHz_str(freq) + << std::endl; bad_tune_freqs.push_back(freq); } } - //Testing for successful lock + // Testing for successful lock if (has_sensor) { bool is_locked = false; - for(int i = 0; i < 1000; i++){ - is_locked = (type == "TX") ? - usrp->get_tx_sensor("lo_locked", 0).to_bool() : - usrp->get_rx_sensor("lo_locked", 0).to_bool(); + for (int i = 0; i < 1000; i++) { + is_locked = (type == "TX") + ? usrp->get_tx_sensor("lo_locked", 0).to_bool() + : usrp->get_rx_sensor("lo_locked", 0).to_bool(); if (is_locked) { break; } std::this_thread::sleep_for(std::chrono::microseconds(1000)); } - if(is_locked){ - if(verbose) std::cout << boost::format("LO successfully locked at %s frequency %s.") - % type % MHz_str(freq) << std::endl; - } - else{ - if(verbose) std::cout << boost::format("LO did not successfully lock at %s frequency %s.") - % type % MHz_str(freq) << std::endl; + if (is_locked) { + if (verbose) + std::cout << boost::format( + "LO successfully locked at %s frequency %s.") + % type % MHz_str(freq) + << std::endl; + } else { + if (verbose) + std::cout << boost::format( + "LO did not successfully lock at %s frequency %s.") + % type % MHz_str(freq) + << std::endl; no_lock_freqs.push_back(freq); } } - if(test_gain){ + if (test_gain) { + // Testing for successful gain tune - //Testing for successful gain tune - - for(double gain: gains){ - if(type == "TX") usrp->set_tx_gain(gain,chan); - else usrp->set_rx_gain(gain,chan); + for (double gain : gains) { + if (type == "TX") + usrp->set_tx_gain(gain, chan); + else + usrp->set_rx_gain(gain, chan); std::this_thread::sleep_for(std::chrono::microseconds(1000)); double actual_gain = (type == "TX") ? usrp->get_tx_gain(chan) : usrp->get_rx_gain(chan); - if(gain == 0.0){ - if(actual_gain == 0.0){ - if(verbose) std::cout << boost::format("Gain successfully set to %5.2f at %s frequency %s.") - % gain % type % MHz_str(freq) << std::endl; - } - else{ - if(verbose) std::cout << boost::format("Gain set to %5.2f instead of %5.2f at %s frequency %s.") - % actual_gain % gain % type % MHz_str(freq) << std::endl; + if (gain == 0.0) { + if (actual_gain == 0.0) { + if (verbose) + std::cout << boost::format("Gain successfully set to %5.2f " + "at %s frequency %s.") + % gain % type % MHz_str(freq) + << std::endl; + } else { + if (verbose) + std::cout << boost::format("Gain set to %5.2f instead of " + "%5.2f at %s frequency %s.") + % actual_gain % gain % type % MHz_str(freq) + << std::endl; bad_gain_vals.push_back(std::make_pair(freq, gain)); } - } - else{ - if((gain / actual_gain) > 0.9999 and (gain / actual_gain) < 1.0001){ - if(verbose) std::cout << boost::format("Gain successfully set to %5.2f at %s frequency %s.") - % gain % type % MHz_str(freq) << std::endl; - } - else{ - if(verbose) std::cout << boost::format("Gain set to %5.2f instead of %5.2f at %s frequency %s.") - % actual_gain % gain % type % MHz_str(freq) << std::endl; + } else { + if ((gain / actual_gain) > 0.9999 and (gain / actual_gain) < 1.0001) { + if (verbose) + std::cout << boost::format("Gain successfully set to %5.2f " + "at %s frequency %s.") + % gain % type % MHz_str(freq) + << std::endl; + } else { + if (verbose) + std::cout << boost::format("Gain set to %5.2f instead of " + "%5.2f at %s frequency %s.") + % actual_gain % gain % type % MHz_str(freq) + << std::endl; bad_gain_vals.push_back(std::make_pair(freq, gain)); } } @@ -239,60 +283,68 @@ std::string coercion_test(uhd::usrp::multi_usrp::sptr usrp, std::string type, in } std::string results = str(boost::format("%s Summary:\n") % type); - if(subdev_name.find("XCVR2450") == 0){ + if (subdev_name.find("XCVR2450") == 0) { results += str(boost::format("Frequency Range: %s - %s, %s - %s\n") % MHz_str(xcvr_freqs[0]) % MHz_str(xcvr_freqs[1]) % MHz_str(xcvr_freqs[2]) % MHz_str(xcvr_freqs[3])); - } - else results += str(boost::format("Frequency Range: %s - %s (Step: %s)\n") - % MHz_str(freqs.front()) % MHz_str(freqs.back()) % MHz_str(freq_step)); - if(test_gain) results += str(boost::format("Gain Range:%5.2f - %5.2f (Step:%5.2f)\n") - % gains.front() % gains.back() % gain_step); - - if(bad_tune_freqs.empty()) results += "USRP successfully tuned to all frequencies."; - else if(bad_tune_freqs.size() > 10 and not verbose){ - //If tuning fails at many values, don't print them all + } else + results += + str(boost::format("Frequency Range: %s - %s (Step: %s)\n") + % MHz_str(freqs.front()) % MHz_str(freqs.back()) % MHz_str(freq_step)); + if (test_gain) + results += str(boost::format("Gain Range:%5.2f - %5.2f (Step:%5.2f)\n") + % gains.front() % gains.back() % gain_step); + + if (bad_tune_freqs.empty()) + results += "USRP successfully tuned to all frequencies."; + else if (bad_tune_freqs.size() > 10 and not verbose) { + // If tuning fails at many values, don't print them all results += str(boost::format("USRP did not successfully tune at %d frequencies.") % bad_tune_freqs.size()); - } - else{ + } else { results += "USRP did not successfully tune to the following frequencies: "; - for(double bad_freq: bad_tune_freqs){ - if(bad_freq != *bad_tune_freqs.begin()) results += ", "; + for (double bad_freq : bad_tune_freqs) { + if (bad_freq != *bad_tune_freqs.begin()) + results += ", "; results += MHz_str(bad_freq); } } - if(has_sensor){ - + if (has_sensor) { results += "\n"; - if(no_lock_freqs.empty()) results += "LO successfully locked at all frequencies."; - else if(no_lock_freqs.size() > 10 and not verbose){ - //If locking fails at many values, don't print them all - results += str(boost::format("USRP did not successfully lock at %d frequencies.") - % no_lock_freqs.size()); - } - else{ + if (no_lock_freqs.empty()) + results += "LO successfully locked at all frequencies."; + else if (no_lock_freqs.size() > 10 and not verbose) { + // If locking fails at many values, don't print them all + results += + str(boost::format("USRP did not successfully lock at %d frequencies.") + % no_lock_freqs.size()); + } else { results += "LO did not lock at the following frequencies: "; - for(double bad_freq: no_lock_freqs){ - if(bad_freq != *no_lock_freqs.begin()) results += ", "; + for (double bad_freq : no_lock_freqs) { + if (bad_freq != *no_lock_freqs.begin()) + results += ", "; results += MHz_str(bad_freq); } } } - if(test_gain){ + if (test_gain) { results += "\n"; - if(bad_gain_vals.empty()) results += "USRP successfully set all specified gain values at all frequencies."; - else if(bad_gain_vals.size() > 10 and not verbose){ - //If gain fails at many values, don't print them all - results += str(boost::format("USRP did not successfully set gain at %d values.") - % bad_gain_vals.size()); - } - else{ - results += "USRP did not successfully set gain under the following circumstances:"; - for(double_pair bad_pair: bad_gain_vals){ + if (bad_gain_vals.empty()) + results += + "USRP successfully set all specified gain values at all frequencies."; + else if (bad_gain_vals.size() > 10 and not verbose) { + // If gain fails at many values, don't print them all + results += + str(boost::format("USRP did not successfully set gain at %d values.") + % bad_gain_vals.size()); + } else { + results += + "USRP did not successfully set gain under the following circumstances:"; + for (double_pair bad_pair : bad_gain_vals) { double bad_freq = bad_pair.first; double bad_gain = bad_pair.second; - results += str(boost::format("\nFrequency: %s, Gain: %5.2f") % MHz_str(bad_freq) % bad_gain); + results += str(boost::format("\nFrequency: %s, Gain: %5.2f") + % MHz_str(bad_freq) % bad_gain); } } } @@ -302,11 +354,11 @@ std::string coercion_test(uhd::usrp::multi_usrp::sptr usrp, std::string type, in /************************************************************************ * Initial Setup -************************************************************************/ - -int UHD_SAFE_MAIN(int argc, char *argv[]){ + ************************************************************************/ - //Variables +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ + // Variables int chan; std::string args; double freq_step, gain_step; @@ -315,7 +367,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::string rx_results; std::string usrp_config; - //Set up the program options + // Set up the program options po::options_description desc("Allowed Options"); // clang-format off desc.add_options() @@ -336,8 +388,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //Help messages, errors - if(vm.count("help") > 0){ + // Help messages, errors + if (vm.count("help") > 0) { std::cout << "UHD Daughterboard Coercion Test\n" "This program tests your USRP daughterboard(s) to\n" "make sure that they can successfully tune to all\n" @@ -346,94 +398,120 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ return EXIT_SUCCESS; } - if(vm.count("tx") + vm.count("rx") == 0){ + if (vm.count("tx") + vm.count("rx") == 0) { std::cout << desc << std::endl; std::cout << "Specify --tx to test for TX frequency coercion\n" "Specify --rx to test for RX frequency coercion\n"; return EXIT_FAILURE; } - //Create a USRP device + // Create a USRP device std::cout << std::endl; uhd::device_addrs_t device_addrs = uhd::device::find(args, uhd::device::USRP); - 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); - std::cout << std::endl << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; + std::cout << std::endl + << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; usrp->set_tx_rate(SAMP_RATE); usrp->set_rx_rate(SAMP_RATE); - //Boolean variables based on command line input - bool test_tx = vm.count("tx") > 0; - bool test_rx = vm.count("rx") > 0; - bool test_tx_gain = !(vm.count("no-tx-gain") > 0) and (usrp->get_tx_gain_range().stop() > 0); - bool test_rx_gain = !(vm.count("no-rx-gain") > 0) and (usrp->get_rx_gain_range().stop() > 0); + // Boolean variables based on command line input + bool test_tx = vm.count("tx") > 0; + bool test_rx = vm.count("rx") > 0; + bool test_tx_gain = !(vm.count("no-tx-gain") > 0) + and (usrp->get_tx_gain_range().stop() > 0); + bool test_rx_gain = !(vm.count("no-rx-gain") > 0) + and (usrp->get_rx_gain_range().stop() > 0); bool verbose = vm.count("verbose") > 0; - if(ref != "internal" and ref != "external" and ref != "mimo"){ + if (ref != "internal" and ref != "external" and ref != "mimo") { std::cout << desc << std::endl; std::cout << "REF must equal internal, external, or mimo." << std::endl; return EXIT_FAILURE; } - //Use TX mboard ID to determine if this is a B2xx, will still return value if there is no TX + // Use TX mboard ID to determine if this is a B2xx, will still return value if there + // is no TX std::string tx_mboard_id = usrp->get_usrp_tx_info(chan).get("mboard_id"); - bool is_b2xx = (tx_mboard_id == "B200" or tx_mboard_id == "B210"); + bool is_b2xx = (tx_mboard_id == "B200" or tx_mboard_id == "B210"); - //Don't perform daughterboard validity checks for B200/B210 - if((not is_b2xx) and test_tx){ + // Don't perform daughterboard validity checks for B200/B210 + if ((not is_b2xx) and test_tx) { std::string tx_dboard_name = usrp->get_usrp_tx_info(chan).get("tx_id"); - if(tx_dboard_name == "Basic TX (0x0000)" or tx_dboard_name == "LF TX (0x000e)"){ + if (tx_dboard_name == "Basic TX (0x0000)" or tx_dboard_name == "LF TX (0x000e)") { std::cout << desc << std::endl; - std::cout << boost::format("This test does not work with the %s daughterboard.") - % tx_dboard_name << std::endl; + std::cout << boost::format( + "This test does not work with the %s daughterboard.") + % tx_dboard_name + << std::endl; return EXIT_FAILURE; - } - else if(tx_dboard_name == "Unknown (0xffff)"){ + } else if (tx_dboard_name == "Unknown (0xffff)") { std::cout << desc << std::endl; - std::cout << "This daughterboard is unrecognized, or there is no TX daughterboard." << std::endl; + std::cout + << "This daughterboard is unrecognized, or there is no TX daughterboard." + << std::endl; return EXIT_FAILURE; } } - //Don't perform daughterboard validity checks for B200/B210 - if((not is_b2xx) and test_rx){ + // Don't perform daughterboard validity checks for B200/B210 + if ((not is_b2xx) and test_rx) { std::string rx_dboard_name = usrp->get_usrp_rx_info(chan).get("rx_id"); - if(rx_dboard_name == "Basic RX (0x0001)" or rx_dboard_name == "LF RX (0x000f)"){ + if (rx_dboard_name == "Basic RX (0x0001)" or rx_dboard_name == "LF RX (0x000f)") { std::cout << desc << std::endl; - std::cout << boost::format("This test does not work with the %s daughterboard.") - % rx_dboard_name << std::endl; + std::cout << boost::format( + "This test does not work with the %s daughterboard.") + % rx_dboard_name + << std::endl; return EXIT_FAILURE; - } - else if(rx_dboard_name == "Unknown (0xffff)"){ + } else if (rx_dboard_name == "Unknown (0xffff)") { std::cout << desc << std::endl; - std::cout << "This daughterboard is unrecognized, or there is no RX daughterboard." << std::endl; + std::cout + << "This daughterboard is unrecognized, or there is no RX daughterboard." + << std::endl; return EXIT_FAILURE; } } - //Setting clock source + // Setting clock source usrp->set_clock_source(ref); std::this_thread::sleep_for(std::chrono::seconds(1)); std::vector<std::string> sensor_names = usrp->get_mboard_sensor_names(0); - if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { - uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); - std::cout << boost::format("Checking MIMO lock: %s ...") % mimo_locked.to_pp_string() << std::endl; + if ((ref == "mimo") + and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") + != sensor_names.end())) { + uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", 0); + std::cout << boost::format("Checking MIMO lock: %s ...") + % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (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); - std::cout << boost::format("Checking REF lock: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (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); + std::cout << boost::format("Checking REF lock: %s ...") + % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } usrp_config = return_usrp_config_string(usrp, chan, test_tx, test_rx, is_b2xx); - if(test_tx) tx_results = coercion_test(usrp, "TX", chan, test_tx_gain, freq_step, gain_step, verbose); - if(test_rx) rx_results = coercion_test(usrp, "RX", chan, test_rx_gain, freq_step, gain_step, verbose); + if (test_tx) + tx_results = + coercion_test(usrp, "TX", chan, test_tx_gain, freq_step, gain_step, verbose); + if (test_rx) + rx_results = + coercion_test(usrp, "RX", chan, test_rx_gain, freq_step, gain_step, verbose); std::cout << std::endl << usrp_config << std::endl << std::endl; - if(test_tx) std::cout << tx_results << std::endl; - if(test_tx and test_rx) std::cout << std::endl; - if(test_rx) std::cout << rx_results << std::endl; + if (test_tx) + std::cout << tx_results << std::endl; + if (test_tx and test_rx) + std::cout << std::endl; + if (test_rx) + std::cout << rx_results << std::endl; return EXIT_SUCCESS; } diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp index 2ff10049d..4d4771900 100644 --- a/host/examples/test_messages.cpp +++ b/host/examples/test_messages.cpp @@ -6,18 +6,18 @@ // #include <uhd/config.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/static.hpp> #include <uhd/types/stream_cmd.hpp> #include <uhd/usrp/multi_usrp.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/static.hpp> +#include <uhd/utils/thread.hpp> #include <boost/assign/list_of.hpp> -#include <boost/program_options.hpp> #include <boost/bind.hpp> #include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <complex> #include <cstdlib> #include <ctime> -#include <complex> #include <iostream> namespace po = boost::program_options; @@ -27,45 +27,45 @@ namespace po = boost::program_options; * Issue a stream command with a time that is in the past. * We expect to get an inline late command message. */ -bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ +bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, + uhd::rx_streamer::sptr rx_stream, + uhd::tx_streamer::sptr) +{ std::cout << "Test late command message... " << std::flush; - usrp->set_time_now(uhd::time_spec_t(200.0)); //set time + usrp->set_time_now(uhd::time_spec_t(200.0)); // set time uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = rx_stream->get_max_num_samps(); + stream_cmd.num_samps = rx_stream->get_max_num_samps(); stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(100.0); //time in the past + stream_cmd.time_spec = uhd::time_spec_t(100.0); // time in the past rx_stream->issue_stream_cmd(stream_cmd); - std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); + std::vector<std::complex<float>> buff(rx_stream->get_max_num_samps()); uhd::rx_metadata_t md; - const size_t nsamps = rx_stream->recv( - &buff.front(), buff.size(), md - ); - - switch(md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: - std::cout << boost::format( - "success:\n" - " Got error code late command message.\n" - ) << std::endl; - return true; - - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - std::cout << boost::format( - "failed:\n" - " Inline message recv timed out.\n" - ) << std::endl; - return false; - - default: - std::cout << boost::format( - "failed:\n" - " Got unexpected error code 0x%x (%s), nsamps %u.\n" - ) % md.error_code % md.strerror() % nsamps << std::endl; - return false; + const size_t nsamps = rx_stream->recv(&buff.front(), buff.size(), md); + + switch (md.error_code) { + case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: + std::cout << boost::format("success:\n" + " Got error code late command message.\n") + << std::endl; + return true; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + std::cout << boost::format("failed:\n" + " Inline message recv timed out.\n") + << std::endl; + return false; + + default: + std::cout << boost::format( + "failed:\n" + " Got unexpected error code 0x%x (%s), nsamps %u.\n") + % md.error_code % md.strerror() % nsamps + << std::endl; + return false; } } @@ -74,46 +74,49 @@ bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streame * Issue a stream command with num samps and more. * We expect to get an inline broken chain message. */ -bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ +bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), + uhd::rx_streamer::sptr rx_stream, + uhd::tx_streamer::sptr) +{ std::cout << "Test broken chain message... " << std::flush; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE); stream_cmd.stream_now = true; - stream_cmd.num_samps = rx_stream->get_max_num_samps(); + stream_cmd.num_samps = rx_stream->get_max_num_samps(); rx_stream->issue_stream_cmd(stream_cmd); - std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); + std::vector<std::complex<float>> buff(rx_stream->get_max_num_samps()); uhd::rx_metadata_t md; - rx_stream->recv( //once for the requested samples - &buff.front(), buff.size(), md - ); - - rx_stream->recv( //again for the inline message - &buff.front(), buff.size(), md - ); - - switch(md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN: - std::cout << boost::format( - "success:\n" - " Got error code broken chain message.\n" - ) << std::endl; - return true; - - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - std::cout << boost::format( - "failed:\n" - " Inline message recv timed out.\n" - ) << std::endl; - return false; - - default: - std::cout << boost::format( - "failed:\n" - " Got unexpected error code 0x%x (%s).\n" - ) % md.error_code % md.strerror() << std::endl; - return false; + rx_stream->recv( // once for the requested samples + &buff.front(), + buff.size(), + md); + + rx_stream->recv( // again for the inline message + &buff.front(), + buff.size(), + md); + + switch (md.error_code) { + case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN: + std::cout << boost::format("success:\n" + " Got error code broken chain message.\n") + << std::endl; + return true; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + std::cout << boost::format("failed:\n" + " Inline message recv timed out.\n") + << std::endl; + return false; + + default: + std::cout << boost::format("failed:\n" + " Got unexpected error code 0x%x (%s).\n") + % md.error_code % md.strerror() + << std::endl; + return false; } } @@ -122,7 +125,9 @@ bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), uhd * Send a burst of many samples that will fragment internally. * We expect to get an burst ack async message. */ -bool test_burst_ack_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr tx_stream){ +bool test_burst_ack_message( + uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr tx_stream) +{ std::cout << "Test burst ack message... " << std::flush; uhd::tx_metadata_t md; @@ -130,33 +135,31 @@ bool test_burst_ack_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, md.end_of_burst = true; md.has_time_spec = false; - //3 times max-sps guarantees a SOB, no burst, and EOB packet - std::vector<std::complex<float> > buff(tx_stream->get_max_num_samps()*3); + // 3 times max-sps guarantees a SOB, no burst, and EOB packet + std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps() * 3); tx_stream->send(&buff.front(), buff.size(), md); uhd::async_metadata_t async_md; - if (not tx_stream->recv_async_msg(async_md)){ - std::cout << boost::format( - "failed:\n" - " Async message recv timed out.\n" - ) << std::endl; + if (not tx_stream->recv_async_msg(async_md)) { + std::cout << boost::format("failed:\n" + " Async message recv timed out.\n") + << std::endl; return false; } - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: - std::cout << boost::format( - "success:\n" - " Got event code burst ack message.\n" - ) << std::endl; - return true; - - default: - std::cout << boost::format( - "failed:\n" - " Got unexpected event code 0x%x.\n" - ) % async_md.event_code << std::endl; - return false; + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + std::cout << boost::format("success:\n" + " Got event code burst ack message.\n") + << std::endl; + return true; + + default: + std::cout << boost::format("failed:\n" + " Got unexpected event code 0x%x.\n") + % async_md.event_code + << std::endl; + return false; } } @@ -165,7 +168,9 @@ bool test_burst_ack_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, * Send a start of burst packet with no following end of burst. * We expect to get an underflow(within a burst) async message. */ -bool test_underflow_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr tx_stream){ +bool test_underflow_message( + uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr tx_stream) +{ std::cout << "Test underflow message... " << std::flush; uhd::tx_metadata_t md; @@ -173,32 +178,30 @@ bool test_underflow_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, md.end_of_burst = false; md.has_time_spec = false; - std::vector< std::complex<float> > buff(tx_stream->get_max_num_samps()); + std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps()); tx_stream->send(&buff.front(), buff.size(), md); uhd::async_metadata_t async_md; - if (not tx_stream->recv_async_msg(async_md, 1)){ - std::cout << boost::format( - "failed:\n" - " Async message recv timed out.\n" - ) << std::endl; + if (not tx_stream->recv_async_msg(async_md, 1)) { + std::cout << boost::format("failed:\n" + " Async message recv timed out.\n") + << std::endl; return false; } - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: - std::cout << boost::format( - "success:\n" - " Got event code underflow message.\n" - ) << std::endl; - return true; - - default: - std::cout << boost::format( - "failed:\n" - " Got unexpected event code 0x%x.\n" - ) % async_md.event_code << std::endl; - return false; + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + std::cout << boost::format("success:\n" + " Got event code underflow message.\n") + << std::endl; + return true; + + default: + std::cout << boost::format("failed:\n" + " Got unexpected event code 0x%x.\n") + % async_md.event_code + << std::endl; + return false; } } @@ -207,73 +210,78 @@ bool test_underflow_message(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, * Send a burst packet that occurs at a time in the past. * We expect to get a time error async message. */ -bool test_time_error_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr tx_stream){ +bool test_time_error_message(uhd::usrp::multi_usrp::sptr usrp, + uhd::rx_streamer::sptr, + uhd::tx_streamer::sptr tx_stream) +{ std::cout << "Test time error message... " << std::flush; uhd::tx_metadata_t md; md.start_of_burst = true; md.end_of_burst = true; md.has_time_spec = true; - md.time_spec = uhd::time_spec_t(100.0); //send at 100s + md.time_spec = uhd::time_spec_t(100.0); // send at 100s - usrp->set_time_now(uhd::time_spec_t(200.0)); //time at 200s + usrp->set_time_now(uhd::time_spec_t(200.0)); // time at 200s - std::vector< std::complex<float> > buff(tx_stream->get_max_num_samps()); + std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps()); tx_stream->send(&buff.front(), buff.size(), md); uhd::async_metadata_t async_md; - if (not tx_stream->recv_async_msg(async_md)){ - std::cout << boost::format( - "failed:\n" - " Async message recv timed out.\n" - ) << std::endl; + if (not tx_stream->recv_async_msg(async_md)) { + std::cout << boost::format("failed:\n" + " Async message recv timed out.\n") + << std::endl; return false; } - switch(async_md.event_code){ - case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: - std::cout << boost::format( - "success:\n" - " Got event code time error message.\n" - ) << std::endl; - return true; - - default: - std::cout << boost::format( - "failed:\n" - " Got unexpected event code 0x%x.\n" - ) % async_md.event_code << std::endl; - return false; + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: + std::cout << boost::format("success:\n" + " Got event code time error message.\n") + << std::endl; + return true; + + default: + std::cout << boost::format("failed:\n" + " Got unexpected event code 0x%x.\n") + % async_md.event_code + << std::endl; + return false; } } -void flush_async(uhd::tx_streamer::sptr tx_stream){ +void flush_async(uhd::tx_streamer::sptr tx_stream) +{ uhd::async_metadata_t async_md; - while (tx_stream->recv_async_msg(async_md)){} + while (tx_stream->recv_async_msg(async_md)) { + } } -void flush_recv(uhd::rx_streamer::sptr rx_stream){ +void flush_recv(uhd::rx_streamer::sptr rx_stream) +{ uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = rx_stream->get_max_num_samps()*3; + stream_cmd.num_samps = rx_stream->get_max_num_samps() * 3; stream_cmd.stream_now = true; rx_stream->issue_stream_cmd(stream_cmd); - std::vector<std::complex<float> > buff(stream_cmd.num_samps); + std::vector<std::complex<float>> buff(stream_cmd.num_samps); uhd::rx_metadata_t md; - do{ + do { rx_stream->recv(&buff.front(), buff.size(), md); } while (md.error_code != uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; size_t ntests; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -287,70 +295,72 @@ 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 Test Messages %s") % desc << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //create RX and TX streamers - uhd::stream_args_t stream_args("fc32"); //complex floats + // create RX and TX streamers + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); //------------------------------------------------------------------ // begin messages test //------------------------------------------------------------------ - static uhd::dict<std::string, boost::function<bool(uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr)> > - tests = boost::assign::map_list_of - ("Test Burst ACK ", &test_burst_ack_message) - ("Test Underflow ", &test_underflow_message) - ("Test Time Error", &test_time_error_message) - ("Test Late Command", &test_late_command_message) - ; + static uhd::dict<std::string, + boost::function<bool( + uhd::usrp::multi_usrp::sptr, uhd::rx_streamer::sptr, uhd::tx_streamer::sptr)>> + tests = boost::assign::map_list_of("Test Burst ACK ", &test_burst_ack_message)( + "Test Underflow ", &test_underflow_message)("Test Time Error", + &test_time_error_message)("Test Late Command", &test_late_command_message); if (vm.count("test-chain")) { tests["Test Broken Chain"] = &test_broken_chain_message; } - //init result counts + // init result counts uhd::dict<std::string, size_t> failures, successes; - for(const std::string &key: tests.keys()){ - failures[key] = 0; + for (const std::string& key : tests.keys()) { + failures[key] = 0; successes[key] = 0; } - //run the tests, pick at random - std::srand((unsigned int) time(NULL)); - for (size_t n = 0; n < ntests; n++){ + // run the tests, pick at random + std::srand((unsigned int)time(NULL)); + for (size_t n = 0; n < ntests; n++) { std::string key = tests.keys()[std::rand() % tests.size()]; - bool pass = tests[key](usrp, rx_stream, tx_stream); + bool pass = tests[key](usrp, rx_stream, tx_stream); flush_recv(rx_stream); flush_async(tx_stream); - //store result - if (pass) successes[key]++; - else failures[key]++; + // store result + if (pass) + successes[key]++; + else + failures[key]++; } - //print the result summary + // print the result summary bool any_failure = false; std::cout << std::endl << "Summary:" << std::endl << std::endl; - for(const std::string &key: tests.keys()){ - std::cout << boost::format( - "%s -> %3u successes, %3u failures" - ) % key % successes[key] % failures[key] << std::endl; + for (const std::string& key : tests.keys()) { + std::cout << boost::format("%s -> %3u successes, %3u failures") % key + % successes[key] % failures[key] + << std::endl; any_failure = any_failure or (failures[key] > 0); } - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return any_failure ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/host/examples/test_pps_input.cpp b/host/examples/test_pps_input.cpp index 5d11b9dcd..24171aa04 100644 --- a/host/examples/test_pps_input.cpp +++ b/host/examples/test_pps_input.cpp @@ -5,26 +5,27 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> -#include <complex> +#include <boost/program_options.hpp> #include <chrono> +#include <complex> +#include <iostream> #include <thread> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; std::string time_source; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -37,31 +38,35 @@ 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 Test PPS Input %s") % desc << std::endl; std::cout - << std::endl - << "Tests if the PPS input signal is working. Will throw an error if not." - << std::endl - << std::endl; + << std::endl + << "Tests if the PPS input signal is working. Will throw an error if not." + << std::endl + << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //sleep off if gpsdo detected and time next pps already set + // sleep off if gpsdo detected and time next pps already set std::this_thread::sleep_for(std::chrono::seconds(1)); - //set time source if specified - if (not time_source.empty()) usrp->set_time_source(time_source); + // set time source if specified + if (not time_source.empty()) + usrp->set_time_source(time_source); - //set the time at an unknown pps (will throw if no pps) - std::cout << std::endl << "Attempt to detect the PPS and set the time..." << std::endl << std::endl; + // set the time at an unknown pps (will throw if no pps) + std::cout << std::endl + << "Attempt to detect the PPS and set the time..." << std::endl + << std::endl; usrp->set_time_unknown_pps(uhd::time_spec_t(0.0)); std::cout << std::endl << "Success!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/test_timed_commands.cpp b/host/examples/test_timed_commands.cpp index f53f3c282..5fe8d818c 100644 --- a/host/examples/test_timed_commands.cpp +++ b/host/examples/test_timed_commands.cpp @@ -5,23 +5,24 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> +#include <boost/program_options.hpp> #include <complex> +#include <iostream> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -33,26 +34,26 @@ 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 Test Timed Commands %s") % desc << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //check if timed commands are supported + // check if timed commands are supported std::cout << std::endl; std::cout << "Testing support for timed commands on this hardware... " << std::flush; - try{ + try { usrp->set_command_time(uhd::time_spec_t(0.0)); usrp->clear_command_time(); - } - catch (const std::exception &e){ + } catch (const std::exception& e) { std::cout << "fail" << std::endl; std::cerr << "Got exception: " << e.what() << std::endl; std::cerr << "Timed commands are not supported on this hardware." << std::endl; @@ -60,27 +61,27 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } std::cout << "pass" << std::endl; - //readback time really fast, time diff is small + // readback time really fast, time diff is small std::cout << std::endl; std::cout << "Perform fast readback of registers:" << std::endl; uhd::time_spec_t total_time; - for (size_t i = 0; i < 100; i++){ + for (size_t i = 0; i < 100; i++) { const uhd::time_spec_t t0 = usrp->get_time_now(); const uhd::time_spec_t t1 = usrp->get_time_now(); - total_time += (t1-t0); + total_time += (t1 - t0); } - std::cout << boost::format( - " Difference between paired reads: %f us" - ) % (total_time.get_real_secs()/100*1e6) << std::endl; - - //test timed control command - //issues get_time_now() command twice a fixed time apart - //outputs difference for each response time vs. the expected time - //and difference between actual and expected time deltas + std::cout << boost::format(" Difference between paired reads: %f us") + % (total_time.get_real_secs() / 100 * 1e6) + << std::endl; + + // test timed control command + // issues get_time_now() command twice a fixed time apart + // outputs difference for each response time vs. the expected time + // and difference between actual and expected time deltas std::cout << std::endl; std::cout << "Testing control timed command:" << std::endl; - const uhd::time_spec_t span = uhd::time_spec_t(0.1); - const uhd::time_spec_t now = usrp->get_time_now(); + const uhd::time_spec_t span = uhd::time_spec_t(0.1); + const uhd::time_spec_t now = usrp->get_time_now(); const uhd::time_spec_t cmd_time1 = now + uhd::time_spec_t(0.1); const uhd::time_spec_t cmd_time2 = cmd_time1 + span; usrp->set_command_time(cmd_time1); @@ -88,63 +89,65 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp->set_command_time(cmd_time2); uhd::time_spec_t response_time2 = usrp->get_time_now(); usrp->clear_command_time(); + std::cout << boost::format(" Span : %f us\n" + " Now : %f us\n" + " Response 1: %f us\n" + " Response 2: %f us") + % (span.get_real_secs() * 1e6) % (now.get_real_secs() * 1e6) + % (response_time1.get_real_secs() * 1e6) + % (response_time2.get_real_secs() * 1e6) + << std::endl; + std::cout << boost::format(" Difference of response time 1: %f us") + % ((response_time1 - cmd_time1).get_real_secs() * 1e6) + << std::endl; + std::cout << boost::format(" Difference of response time 2: %f us") + % ((response_time2 - cmd_time2).get_real_secs() * 1e6) + << std::endl; std::cout << boost::format( - " Span : %f us\n" - " Now : %f us\n" - " Response 1: %f us\n" - " Response 2: %f us" - ) % (span.get_real_secs()*1e6) % (now.get_real_secs()*1e6) % (response_time1.get_real_secs()*1e6) % (response_time2.get_real_secs()*1e6) << std::endl; - std::cout << boost::format( - " Difference of response time 1: %f us" - ) % ((response_time1 - cmd_time1).get_real_secs()*1e6) << std::endl; - std::cout << boost::format( - " Difference of response time 2: %f us" - ) % ((response_time2 - cmd_time2).get_real_secs()*1e6) << std::endl; - std::cout << boost::format( - " Difference between actual and expected time delta: %f us" - ) % ((response_time2 - response_time1 - span).get_real_secs()*1e6) << std::endl; - - //use a timed command to start a stream at a specific time - //this is not the right way start streaming at time x, - //but it should approximate it within control RTT/2 - //setup streaming + " Difference between actual and expected time delta: %f us") + % ((response_time2 - response_time1 - span).get_real_secs() * 1e6) + << std::endl; + + // use a timed command to start a stream at a specific time + // this is not the right way start streaming at time x, + // but it should approximate it within control RTT/2 + // setup streaming std::cout << std::endl; std::cout << "About to start streaming using timed command:" << std::endl; - //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); uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = 100; - stream_cmd.stream_now = false; + stream_cmd.num_samps = 100; + stream_cmd.stream_now = false; const uhd::time_spec_t stream_time = usrp->get_time_now() + uhd::time_spec_t(0.1); - stream_cmd.time_spec = stream_time; + stream_cmd.time_spec = stream_time; rx_stream->issue_stream_cmd(stream_cmd); - //meta-data will be filled in by recv() + // meta-data will be filled in by recv() uhd::rx_metadata_t md; - //allocate buffer to receive with samples - std::vector<std::complex<float> > buff(stream_cmd.num_samps); + // allocate buffer to receive with samples + std::vector<std::complex<float>> buff(stream_cmd.num_samps); const size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md, 1.0); - 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())); } - std::cout << boost::format( - " Received packet: %u samples, %u full secs, %f frac secs" - ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; - std::cout << boost::format( - " Stream time was: %u full secs, %f frac secs" - ) % stream_time.get_full_secs() % stream_time.get_frac_secs() << std::endl; - std::cout << boost::format( - " Difference between stream time and first packet: %f us" - ) % ((md.time_spec-stream_time).get_real_secs()*1e6) << std::endl; - - //finished + std::cout << boost::format(" Received packet: %u samples, %u full secs, %f frac secs") + % num_rx_samps % md.time_spec.get_full_secs() + % md.time_spec.get_frac_secs() + << std::endl; + std::cout << boost::format(" Stream time was: %u full secs, %f frac secs") + % stream_time.get_full_secs() % stream_time.get_frac_secs() + << std::endl; + std::cout << boost::format(" Difference between stream time and first packet: %f us") + % ((md.time_spec - stream_time).get_real_secs() * 1e6) + << std::endl; + + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/twinrx_freq_hopping.cpp b/host/examples/twinrx_freq_hopping.cpp index f4ce3e528..ea350928c 100644 --- a/host/examples/twinrx_freq_hopping.cpp +++ b/host/examples/twinrx_freq_hopping.cpp @@ -7,15 +7,12 @@ // FFT conversion #include "ascii_art_dft.hpp" - -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> - +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/program_options.hpp> #include <boost/thread.hpp> #include <boost/thread/thread_time.hpp> - #include <fstream> /* @@ -23,8 +20,8 @@ * motherboard and a TwinRX daughterboard. * * The TwinRX daughterboard is different than previous daughterboards in that it has two - * RX channels, each with a set of Local Oscillators (LOs). Either channel can be configured - * to use either LO set, allowing for the two channels to share an LO source. + * RX channels, each with a set of Local Oscillators (LOs). Either channel can be + * configured to use either LO set, allowing for the two channels to share an LO source. * * The TwinRX can be used like any other daughterboard, as the multi_usrp::set_rx_freq() * function will automatically calculate and set the two LO frequencies as needed. @@ -35,7 +32,8 @@ * * 1. Tune across the given frequency range, storing the calculated LO frequencies along * the way. - * 2. Use timed commands to tell the TwinRX to receive bursts of samples at given intervals. + * 2. Use timed commands to tell the TwinRX to receive bursts of samples at given + * intervals. * 3. For each frequency, tune the LOs for the inactive channel for the next frequency and * receive at the current frequency. * 4. If applicable, send the next timed command for streaming. @@ -44,7 +42,7 @@ namespace pt = boost::posix_time; namespace po = boost::program_options; -typedef std::vector<std::complex<float> > recv_buff_t; +typedef std::vector<std::complex<float>> recv_buff_t; typedef std::vector<recv_buff_t> recv_buffs_t; // Global objects @@ -67,8 +65,8 @@ const int X300_COMMAND_FIFO_DEPTH = 16; // This is a helper function for receiving samples from the USRP -static void twinrx_recv(recv_buff_t &buffer) { - +static void twinrx_recv(recv_buff_t& buffer) +{ size_t num_acc_samps = 0; uhd::rx_metadata_t md; @@ -77,9 +75,10 @@ static void twinrx_recv(recv_buff_t &buffer) { size_t num_to_recv = std::min<size_t>(recv_spb, (spb - num_acc_samps)); // recv call will block until samples are ready or the call times out - size_t num_recvd = rx_stream->recv(&buffer[num_acc_samps], num_to_recv, md, receive_interval); + size_t num_recvd = + rx_stream->recv(&buffer[num_acc_samps], num_to_recv, md, receive_interval); - if(md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::cout << md.strerror() << std::endl; break; } @@ -88,18 +87,20 @@ static void twinrx_recv(recv_buff_t &buffer) { } // Function to write the acquisition FFT to a binary file -static void write_fft_to_file(const std::string &fft_path) { +static void write_fft_to_file(const std::string& fft_path) +{ std::cout << "Calculating FFTs (this may take a while)... " << std::flush; std::ofstream ofile(fft_path.c_str(), std::ios::binary); - BOOST_FOREACH(const recv_buff_t &buff, buffs) { - std::vector<float> fft = ascii_art_dft::log_pwr_dft(&buff.front(), buff.size()); - ofile.write((char*)&fft[0], (sizeof(float)*fft.size())); - } + BOOST_FOREACH (const recv_buff_t& buff, buffs) { + std::vector<float> fft = ascii_art_dft::log_pwr_dft(&buff.front(), buff.size()); + ofile.write((char*)&fft[0], (sizeof(float) * fft.size())); + } ofile.close(); std::cout << "done." << std::endl; } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); // Program options @@ -129,22 +130,25 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - if(vm.count("help")) { + if (vm.count("help")) { std::cout << "TwinRX Frequency Hopping Example - " << desc << std::endl; return EXIT_SUCCESS; } // Create a USRP device - std::cout << boost::format("\nCreating the USRP device with args: \"%s\"...\n") % args; + std::cout << boost::format("\nCreating the USRP device with args: \"%s\"...\n") + % args; usrp = uhd::usrp::multi_usrp::make(args); // Make sure the USRP is an X3xx with a TwinRX uhd::dict<std::string, std::string> info = usrp->get_usrp_rx_info(); - if(info.get("mboard_id").find("X3") == std::string::npos) { - throw uhd::runtime_error("This example can only be used with an X-Series motherboard."); + if (info.get("mboard_id").find("X3") == std::string::npos) { + throw uhd::runtime_error( + "This example can only be used with an X-Series motherboard."); } - if(info.get("rx_id").find("TwinRX") == std::string::npos) { - throw uhd::runtime_error("This example can only be used with a TwinRX daughterboard."); + if (info.get("rx_id").find("TwinRX") == std::string::npos) { + throw uhd::runtime_error( + "This example can only be used with a TwinRX daughterboard."); } // Validate frequency range @@ -156,26 +160,31 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ end_freq = rx_freq_range.stop(); } if (start_freq < rx_freq_range.start() or end_freq > rx_freq_range.stop()) { - throw uhd::runtime_error((boost::format("Start and stop frequencies must be between %d and %d MHz") - % (rx_freq_range.start() / 1e6) % (rx_freq_range.stop() / 1e6)).str()); + throw uhd::runtime_error( + (boost::format("Start and stop frequencies must be between %d and %d MHz") + % (rx_freq_range.start() / 1e6) % (rx_freq_range.stop() / 1e6)) + .str()); } if (start_freq > end_freq) { throw uhd::runtime_error("Start frequency must be less than end frequency."); } if ((end_freq - start_freq) > 0 and (end_freq - start_freq) < rate) { - throw uhd::runtime_error("The sample rate must be less than the range between the start and end frequencies."); + throw uhd::runtime_error("The sample rate must be less than the range between " + "the start and end frequencies."); } // Set TwinRX settings usrp->set_rx_subdev_spec(subdev); - // Set the unused channel to not use any LOs. This allows the active channel to control them. + // Set the unused channel to not use any LOs. This allows the active channel to + // control them. usrp->set_rx_lo_source("disabled", uhd::usrp::multi_usrp::ALL_LOS, UNUSED_CHAN); // Set user settings std::cout << boost::format("Setting antenna to: %s\n") % ant; usrp->set_rx_antenna(ant, ACTIVE_CHAN); - std::cout << boost::format("Actual antenna: %s\n") % usrp->get_rx_antenna(ACTIVE_CHAN); + std::cout << boost::format("Actual antenna: %s\n") + % usrp->get_rx_antenna(ACTIVE_CHAN); std::cout << boost::format("Setting sample rate to: %d\n") % rate; usrp->set_rx_rate(rate); @@ -189,7 +198,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::stream_args_t stream_args("fc32", "sc16"); stream_args.channels.push_back(0); rx_stream = usrp->get_rx_stream(stream_args); - recv_spb = rx_stream->get_max_num_samps(); + recv_spb = rx_stream->get_max_num_samps(); // Calculate the frequency hops for (double rx_freq = start_freq; rx_freq <= end_freq; rx_freq += rate) { @@ -204,10 +213,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp->set_rx_freq(rf_freqs[0], ACTIVE_CHAN); usrp->set_time_now(uhd::time_spec_t(0.0)); - // Configure the stream command which will be issued to acquire samples at each frequency - stream_cmd.num_samps = spb; + // Configure the stream command which will be issued to acquire samples at each + // frequency + stream_cmd.num_samps = spb; stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(0.0); + stream_cmd.time_spec = uhd::time_spec_t(0.0); // Stream commands will be scheduled at regular intervals uhd::time_spec_t receive_interval_ts = uhd::time_spec_t(receive_interval); @@ -216,14 +226,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t num_initial_cmds = std::min<size_t>(X300_COMMAND_FIFO_DEPTH, rf_freqs.size()); size_t num_issued_commands; - for (num_issued_commands = 0; num_issued_commands < num_initial_cmds; num_issued_commands++) { + for (num_issued_commands = 0; num_issued_commands < num_initial_cmds; + num_issued_commands++) { stream_cmd.time_spec += receive_interval_ts; rx_stream->issue_stream_cmd(stream_cmd); } // Hop frequencies and acquire bursts of samples at each until done sweeping - while(1) { - + while (1) { std::cout << "Scanning..." << std::endl; auto start_time = boost::get_system_time(); @@ -234,11 +244,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp->set_rx_lo_source(lo_src, uhd::usrp::multi_usrp::ALL_LOS, ACTIVE_CHAN); // Preconfigure the next frequency - usrp->set_rx_freq(rf_freqs[(i+1) % rf_freqs.size()], UNUSED_CHAN); + usrp->set_rx_freq(rf_freqs[(i + 1) % rf_freqs.size()], UNUSED_CHAN); // Program the current frequency - // This frequency was already pre-programmed in the previous iteration so the local oscillators - // are already tuned. This call will only configure front-end filter, amplifiers, etc + // This frequency was already pre-programmed in the previous iteration so the + // local oscillators are already tuned. This call will only configure + // front-end filter, amplifiers, etc usrp->set_rx_freq(rf_freqs[i], ACTIVE_CHAN); // Receive one burst of samples @@ -253,16 +264,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } auto end_time = boost::get_system_time(); - std::cout - << boost::format("Sweep done in %d milliseconds.\n") - % ((end_time - start_time).total_milliseconds() * 1000); + std::cout << boost::format("Sweep done in %d milliseconds.\n") + % ((end_time - start_time).total_milliseconds() * 1000); // Optionally convert received samples to FFT and write to file - if(vm.count("fft-path")) { + if (vm.count("fft-path")) { write_fft_to_file(fft_path); } - if (!vm.count("repeat")){ + if (!vm.count("repeat")) { break; } } @@ -272,4 +282,3 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp.reset(); return EXIT_SUCCESS; } - diff --git a/host/examples/tx_bursts.cpp b/host/examples/tx_bursts.cpp index 3f179b47c..4be4e694b 100644 --- a/host/examples/tx_bursts.cpp +++ b/host/examples/tx_bursts.cpp @@ -5,26 +5,30 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/format.hpp> #include <boost/program_options.hpp> #include <boost/thread/thread.hpp> -#include <boost/format.hpp> -#include <boost/algorithm/string.hpp> +#include <complex> #include <csignal> #include <iostream> -#include <complex> namespace po = boost::program_options; static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, channel_list; double seconds_in_future; size_t total_num_samps; @@ -34,7 +38,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ double rep_rate; double gain; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -57,110 +61,116 @@ 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 TX Timed Samples %s") % desc << std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; - bool repeat = vm.count("repeat") != 0; + bool repeat = vm.count("repeat") != 0; - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //detect which channels to use + // detect which channels to use std::vector<std::string> channel_strings; std::vector<size_t> channel_nums; boost::split(channel_strings, channel_list, boost::is_any_of("\"',")); - for(size_t ch = 0; ch < channel_strings.size(); ch++){ + for (size_t ch = 0; ch < channel_strings.size(); ch++) { size_t chan = std::stoi(channel_strings[ch]); - if(chan >= usrp->get_tx_num_channels()){ + if (chan >= usrp->get_tx_num_channels()) { throw std::runtime_error("Invalid channel(s) specified."); - } - else channel_nums.push_back(std::stoi(channel_strings[ch])); + } else + channel_nums.push_back(std::stoi(channel_strings[ch])); } - //set the tx sample rate - std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + // set the tx sample rate + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6) + << std::endl + << std::endl; - std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; - for(size_t i=0; i < channel_nums.size(); i++){ + std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq / 1e6) << std::endl; + for (size_t i = 0; i < channel_nums.size(); i++) { uhd::tune_request_t tune_request(freq); - if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("int-n")) + tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_tx_freq(tune_request, channel_nums[i]); } - std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq() / 1e6) + << std::endl + << std::endl; std::cout << boost::format("Setting TX Gain: %f...") % (gain) << std::endl; - for(size_t i=0; i < channel_nums.size(); i++) usrp->set_tx_gain(gain, channel_nums[i]); - std::cout << boost::format("Actual TX Gain: %f...") % (usrp->get_tx_gain()) << std::endl << std::endl; + for (size_t i = 0; i < channel_nums.size(); i++) + usrp->set_tx_gain(gain, channel_nums[i]); + std::cout << boost::format("Actual TX Gain: %f...") % (usrp->get_tx_gain()) + << std::endl + << std::endl; std::cout << boost::format("Setting device timestamp to 0...") << std::endl; usrp->set_time_now(uhd::time_spec_t(0.0)); - //create a transmit streamer - uhd::stream_args_t stream_args("fc32"); //complex floats - stream_args.channels = channel_nums; + // create a transmit streamer + uhd::stream_args_t stream_args("fc32"); // complex floats + stream_args.channels = channel_nums; uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //allocate buffer with data to send + // allocate buffer with data to send const size_t spb = tx_stream->get_max_num_samps(); - std::vector<std::complex<float> > buff(spb, std::complex<float>(ampl, ampl)); - std::vector<std::complex<float> *> buffs(channel_nums.size(), &buff.front()); + std::vector<std::complex<float>> buff(spb, std::complex<float>(ampl, ampl)); + std::vector<std::complex<float>*> buffs(channel_nums.size(), &buff.front()); std::signal(SIGINT, &sig_int_handler); - if(repeat) std::cout << "Press Ctrl + C to quit..." << std::endl; + if (repeat) + std::cout << "Press Ctrl + C to quit..." << std::endl; double time_to_send = seconds_in_future; do { - //setup metadata for the first packet + // setup metadata for the first packet uhd::tx_metadata_t md; md.start_of_burst = true; - md.end_of_burst = false; - md.has_time_spec = true; - md.time_spec = uhd::time_spec_t(time_to_send); + md.end_of_burst = false; + md.has_time_spec = true; + md.time_spec = uhd::time_spec_t(time_to_send); - //the first call to send() will block this many seconds before sending: - double timeout = std::max(rep_rate, seconds_in_future) + 0.1; //timeout (delay before transmit + padding) + // the first call to send() will block this many seconds before sending: + double timeout = std::max(rep_rate, seconds_in_future) + + 0.1; // timeout (delay before transmit + padding) - size_t num_acc_samps = 0; //number of accumulated samples - while(num_acc_samps < total_num_samps){ + size_t num_acc_samps = 0; // number of accumulated samples + while (num_acc_samps < total_num_samps) { size_t samps_to_send = total_num_samps - num_acc_samps; - if (samps_to_send > spb) - { + if (samps_to_send > spb) { samps_to_send = spb; } else { md.end_of_burst = true; } - //send a single packet - size_t num_tx_samps = tx_stream->send( - buffs, samps_to_send, md, timeout - ); - //do not use time spec for subsequent packets - md.has_time_spec = false; + // send a single packet + size_t num_tx_samps = tx_stream->send(buffs, samps_to_send, md, timeout); + // do not use time spec for subsequent packets + md.has_time_spec = false; md.start_of_burst = false; - if (num_tx_samps < samps_to_send) - { + if (num_tx_samps < samps_to_send) { std::cerr << "Send timeout..." << std::endl; - if (stop_signal_called) - { + if (stop_signal_called) { exit(EXIT_FAILURE); } } - if(verbose) - { - std::cout << boost::format("Sent packet: %u samples") % num_tx_samps << std::endl; + if (verbose) { + std::cout << boost::format("Sent packet: %u samples") % num_tx_samps + << std::endl; } num_acc_samps += num_tx_samps; @@ -171,18 +181,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << std::endl << "Waiting for async burst ACK... " << std::flush; uhd::async_metadata_t async_md; size_t acks = 0; - //loop through all messages for the ACK packets (may have underflow messages in queue) - while (acks < channel_nums.size() and tx_stream->recv_async_msg(async_md, seconds_in_future)) - { - if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) - { + // loop through all messages for the ACK packets (may have underflow messages in + // queue) + while (acks < channel_nums.size() + and tx_stream->recv_async_msg(async_md, seconds_in_future)) { + if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) { acks++; } } std::cout << (acks == channel_nums.size() ? "success" : "fail") << std::endl; } while (not stop_signal_called and repeat); - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp index 40974b4a2..d2de72a68 100644 --- a/host/examples/tx_samples_from_file.cpp +++ b/host/examples/tx_samples_from_file.cpp @@ -6,41 +6,41 @@ // #include <uhd/types/tune_request.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <iostream> -#include <fstream> +#include <boost/program_options.hpp> +#include <chrono> #include <complex> #include <csignal> -#include <chrono> +#include <fstream> +#include <iostream> #include <thread> namespace po = boost::program_options; static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} - -template<typename samp_type> void send_from_file( - uhd::tx_streamer::sptr tx_stream, - const std::string &file, - size_t samps_per_buff -){ +void sig_int_handler(int) +{ + stop_signal_called = true; +} +template <typename samp_type> +void send_from_file( + uhd::tx_streamer::sptr tx_stream, const std::string& file, size_t samps_per_buff) +{ uhd::tx_metadata_t md; md.start_of_burst = false; - md.end_of_burst = false; + md.end_of_burst = false; std::vector<samp_type> buff(samps_per_buff); std::ifstream infile(file.c_str(), std::ifstream::binary); - //loop until the entire file has been read - - while(not md.end_of_burst and not stop_signal_called){ + // loop until the entire file has been read - infile.read((char*)&buff.front(), buff.size()*sizeof(samp_type)); - size_t num_tx_samps = size_t(infile.gcount()/sizeof(samp_type)); + while (not md.end_of_burst and not stop_signal_called) { + infile.read((char*)&buff.front(), buff.size() * sizeof(samp_type)); + size_t num_tx_samps = size_t(infile.gcount() / sizeof(samp_type)); md.end_of_burst = infile.eof(); @@ -50,15 +50,16 @@ template<typename samp_type> void send_from_file( infile.close(); } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, file, type, ant, subdev, ref, wirefmt, channel; size_t spb; double rate, freq, gain, bw, delay, lo_offset; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -89,125 +90,149 @@ 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 TX samples from file %s") % desc << std::endl; return ~0; } bool repeat = vm.count("repeat") > 0; - //create a usrp device + // create a usrp device 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); - //Lock mboard clocks + // Lock mboard clocks usrp->set_clock_source(ref); - //always select the subdevice first, the channel mapping affects the other settings - if (vm.count("subdev")) usrp->set_tx_subdev_spec(subdev); + // always select the subdevice first, the channel mapping affects the other settings + if (vm.count("subdev")) + usrp->set_tx_subdev_spec(subdev); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //set the sample rate - if (not vm.count("rate")){ + // set the sample rate + if (not vm.count("rate")) { std::cerr << "Please specify the sample rate with --rate" << std::endl; return ~0; } - std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6) + << std::endl + << std::endl; - //set the center frequency - if (not vm.count("freq")){ + // set the center frequency + if (not vm.count("freq")) { std::cerr << "Please specify the center frequency with --freq" << std::endl; return ~0; } - std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; - std::cout << boost::format("Setting TX LO Offset: %f MHz...") % (lo_offset/1e6) << std::endl; + std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq / 1e6) << std::endl; + std::cout << boost::format("Setting TX LO Offset: %f MHz...") % (lo_offset / 1e6) + << std::endl; uhd::tune_request_t tune_request; tune_request = uhd::tune_request_t(freq, lo_offset); - if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("int-n")) + tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_tx_freq(tune_request); - std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq() / 1e6) + << std::endl + << std::endl; - //set the rf gain - if (vm.count("gain")){ + // set the rf gain + if (vm.count("gain")) { std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl; usrp->set_tx_gain(gain); - std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain() << std::endl << std::endl; + std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain() + << std::endl + << std::endl; } - //set the analog frontend filter bandwidth - if (vm.count("bw")){ - std::cout << boost::format("Setting TX Bandwidth: %f MHz...") - % (bw / 1e6) + // set the analog frontend filter bandwidth + if (vm.count("bw")) { + std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % (bw / 1e6) << std::endl; usrp->set_tx_bandwidth(bw); std::cout << boost::format("Actual TX Bandwidth: %f MHz...") - % (usrp->get_tx_bandwidth() / 1e6) - << std::endl << std::endl; + % (usrp->get_tx_bandwidth() / 1e6) + << std::endl + << std::endl; } - //set the antenna - if (vm.count("ant")) usrp->set_tx_antenna(ant); + // set the antenna + if (vm.count("ant")) + usrp->set_tx_antenna(ant); - //allow for some setup time: + // allow for some setup time: std::this_thread::sleep_for(std::chrono::seconds(1)); - //Check Ref and LO Lock detect + // Check Ref and LO Lock detect std::vector<std::string> sensor_names; sensor_names = usrp->get_tx_sensor_names(0); - if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { - uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked",0); - std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl; + if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") + != sensor_names.end()) { + uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked", 0); + std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } sensor_names = usrp->get_mboard_sensor_names(0); - if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { - uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); - std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl; + if ((ref == "mimo") + and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") + != sensor_names.end())) { + uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", 0); + std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (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); - std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (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); + std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } - //set sigint if user wants to receive - if(repeat){ + // set sigint if user wants to receive + if (repeat) { std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; } - //create a transmit streamer + // create a transmit streamer std::string cpu_format; std::vector<size_t> channel_nums; - if (type == "double") cpu_format = "fc64"; - else if (type == "float") cpu_format = "fc32"; - else if (type == "short") cpu_format = "sc16"; + if (type == "double") + cpu_format = "fc64"; + else if (type == "float") + cpu_format = "fc32"; + else if (type == "short") + cpu_format = "sc16"; uhd::stream_args_t stream_args(cpu_format, wirefmt); channel_nums.push_back(boost::lexical_cast<size_t>(channel)); - stream_args.channels = channel_nums; + stream_args.channels = channel_nums; uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //send from file - do{ - if (type == "double") send_from_file<std::complex<double> >(tx_stream, file, spb); - else if (type == "float") send_from_file<std::complex<float> >(tx_stream, file, spb); - else if (type == "short") send_from_file<std::complex<short> >(tx_stream, file, spb); - else throw std::runtime_error("Unknown type " + type); - - if(repeat and delay > 0.0) { - std::this_thread::sleep_for( - std::chrono::milliseconds(int64_t(delay*1000)) - ); + // send from file + do { + if (type == "double") + send_from_file<std::complex<double>>(tx_stream, file, spb); + else if (type == "float") + send_from_file<std::complex<float>>(tx_stream, file, spb); + else if (type == "short") + send_from_file<std::complex<short>>(tx_stream, file, spb); + else + throw std::runtime_error("Unknown type " + type); + + if (repeat and delay > 0.0) { + std::this_thread::sleep_for(std::chrono::milliseconds(int64_t(delay * 1000))); } - } while(repeat and not stop_signal_called); + } while (repeat and not stop_signal_called); - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index b57578939..5ec5dbc23 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -5,21 +5,22 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/format.hpp> #include <boost/program_options.hpp> #include <boost/thread/thread.hpp> -#include <boost/format.hpp> -#include <iostream> #include <complex> +#include <iostream> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args; std::string wire; double seconds_in_future; @@ -27,7 +28,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ double rate; float ampl; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -45,77 +46,84 @@ 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 TX Timed Samples %s") % desc << std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; - //create a usrp device + // create a usrp device 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); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //set the tx sample rate - std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + // set the tx sample rate + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6) + << std::endl + << std::endl; std::cout << boost::format("Setting device timestamp to 0...") << std::endl; usrp->set_time_now(uhd::time_spec_t(0.0)); - //create a transmit streamer - uhd::stream_args_t stream_args("fc32", wire); //complex floats + // create a transmit streamer + uhd::stream_args_t stream_args("fc32", wire); // complex floats uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //allocate buffer with data to send - std::vector<std::complex<float> > buff(tx_stream->get_max_num_samps(), std::complex<float>(ampl, ampl)); + // allocate buffer with data to send + std::vector<std::complex<float>> buff( + tx_stream->get_max_num_samps(), std::complex<float>(ampl, ampl)); - //setup metadata for the first packet + // setup metadata for the first packet uhd::tx_metadata_t md; md.start_of_burst = false; - md.end_of_burst = false; - md.has_time_spec = true; - md.time_spec = uhd::time_spec_t(seconds_in_future); + md.end_of_burst = false; + md.has_time_spec = true; + md.time_spec = uhd::time_spec_t(seconds_in_future); - //the first call to send() will block this many seconds before sending: - const double timeout = seconds_in_future + 0.1; //timeout (delay before transmit + padding) + // the first call to send() will block this many seconds before sending: + const double timeout = + seconds_in_future + 0.1; // timeout (delay before transmit + padding) - size_t num_acc_samps = 0; //number of accumulated samples - while(num_acc_samps < total_num_samps){ + size_t num_acc_samps = 0; // number of accumulated samples + while (num_acc_samps < total_num_samps) { size_t samps_to_send = std::min(total_num_samps - num_acc_samps, buff.size()); - //send a single packet - size_t num_tx_samps = tx_stream->send( - &buff.front(), samps_to_send, md, timeout - ); + // send a single packet + size_t num_tx_samps = tx_stream->send(&buff.front(), samps_to_send, md, timeout); - //do not use time spec for subsequent packets + // do not use time spec for subsequent packets md.has_time_spec = false; - if (num_tx_samps < samps_to_send) std::cerr << "Send timeout..." << std::endl; - if(verbose) std::cout << boost::format("Sent packet: %u samples") % num_tx_samps << std::endl; + if (num_tx_samps < samps_to_send) + std::cerr << "Send timeout..." << std::endl; + if (verbose) + std::cout << boost::format("Sent packet: %u samples") % num_tx_samps + << std::endl; num_acc_samps += num_tx_samps; } - //send a mini EOB packet - md.end_of_burst = true; + // send a mini EOB packet + md.end_of_burst = true; tx_stream->send("", 0, md); std::cout << std::endl << "Waiting for async burst ACK... " << std::flush; uhd::async_metadata_t async_md; bool got_async_burst_ack = false; - //loop through all messages for the ACK packet (may have underflow messages in queue) - while (not got_async_burst_ack and tx_stream->recv_async_msg(async_md, timeout)){ - got_async_burst_ack = (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK); + // loop through all messages for the ACK packet (may have underflow messages in queue) + while (not got_async_burst_ack and tx_stream->recv_async_msg(async_md, timeout)) { + got_async_burst_ack = + (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK); } - std::cout << (got_async_burst_ack? "success" : "fail") << std::endl; + std::cout << (got_async_burst_ack ? "success" : "fail") << std::endl; - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp index 1698c019d..5eb52f34c 100644 --- a/host/examples/tx_waveforms.cpp +++ b/host/examples/tx_waveforms.cpp @@ -6,20 +6,20 @@ // #include "wavetable.hpp" -#include <uhd/utils/thread.hpp> +#include <uhd/exception.hpp> +#include <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/utils/static.hpp> -#include <uhd/usrp/multi_usrp.hpp> -#include <uhd/exception.hpp> -#include <boost/program_options.hpp> -#include <boost/math/special_functions/round.hpp> -#include <boost/format.hpp> -#include <boost/algorithm/string.hpp> +#include <uhd/utils/thread.hpp> #include <stdint.h> -#include <iostream> +#include <boost/algorithm/string.hpp> +#include <boost/format.hpp> +#include <boost/math/special_functions/round.hpp> +#include <boost/program_options.hpp> +#include <chrono> #include <csignal> +#include <iostream> #include <string> -#include <chrono> #include <thread> namespace po = boost::program_options; @@ -28,22 +28,26 @@ namespace po = boost::program_options; * Signal handlers **********************************************************************/ static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} /*********************************************************************** * Main function **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //variables to be set by po + // variables to be set by po std::string args, wave_type, ant, subdev, ref, pps, otw, channel_list; uint64_t total_num_samps; size_t spb; double rate, freq, gain, wave_freq, bw, lo_offset; float ampl; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -73,170 +77,194 @@ 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 TX Waveforms %s") % desc << std::endl; return ~0; } - //create a usrp device + // create a usrp device 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); - //always select the subdevice first, the channel mapping affects the other settings - if (vm.count("subdev")) usrp->set_tx_subdev_spec(subdev); + // always select the subdevice first, the channel mapping affects the other settings + if (vm.count("subdev")) + usrp->set_tx_subdev_spec(subdev); - //detect which channels to use + // detect which channels to use std::vector<std::string> channel_strings; std::vector<size_t> channel_nums; boost::split(channel_strings, channel_list, boost::is_any_of("\"',")); - for(size_t ch = 0; ch < channel_strings.size(); ch++){ + for (size_t ch = 0; ch < channel_strings.size(); ch++) { size_t chan = std::stoi(channel_strings[ch]); - if(chan >= usrp->get_tx_num_channels()) + if (chan >= usrp->get_tx_num_channels()) throw std::runtime_error("Invalid channel(s) specified."); else channel_nums.push_back(std::stoi(channel_strings[ch])); } - //Lock mboard clocks + // Lock mboard clocks usrp->set_clock_source(ref); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; - //set the sample rate - if (not vm.count("rate")){ + // set the sample rate + if (not vm.count("rate")) { std::cerr << "Please specify the sample rate with --rate" << std::endl; return ~0; } - std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6) + << std::endl + << std::endl; - //set the center frequency - if (not vm.count("freq")){ + // set the center frequency + if (not vm.count("freq")) { std::cerr << "Please specify the center frequency with --freq" << std::endl; return ~0; } - for(size_t ch = 0; ch < channel_nums.size(); ch++) { - std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; - std::cout << boost::format("Setting TX LO Offset: %f MHz...") % (lo_offset/1e6) + for (size_t ch = 0; ch < channel_nums.size(); ch++) { + std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq / 1e6) + << std::endl; + std::cout << boost::format("Setting TX LO Offset: %f MHz...") % (lo_offset / 1e6) << std::endl; uhd::tune_request_t tune_request(freq, lo_offset); - if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("int-n")) + tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_tx_freq(tune_request, channel_nums[ch]); - std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq(channel_nums[ch])/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Freq: %f MHz...") + % (usrp->get_tx_freq(channel_nums[ch]) / 1e6) + << std::endl + << std::endl; - //set the rf gain - if (vm.count("gain")){ + // set the rf gain + if (vm.count("gain")) { std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl; usrp->set_tx_gain(gain, channel_nums[ch]); - std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain(channel_nums[ch]) << std::endl << std::endl; + std::cout << boost::format("Actual TX Gain: %f dB...") + % usrp->get_tx_gain(channel_nums[ch]) + << std::endl + << std::endl; } - //set the analog frontend filter bandwidth - if (vm.count("bw")){ - std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % bw << std::endl; + // set the analog frontend filter bandwidth + if (vm.count("bw")) { + std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % bw + << std::endl; usrp->set_tx_bandwidth(bw, channel_nums[ch]); - std::cout << boost::format("Actual TX Bandwidth: %f MHz...") % usrp->get_tx_bandwidth(channel_nums[ch]) << std::endl << std::endl; + std::cout << boost::format("Actual TX Bandwidth: %f MHz...") + % usrp->get_tx_bandwidth(channel_nums[ch]) + << std::endl + << std::endl; } - //set the antenna - if (vm.count("ant")) usrp->set_tx_antenna(ant, channel_nums[ch]); + // set the antenna + if (vm.count("ant")) + usrp->set_tx_antenna(ant, channel_nums[ch]); } - std::this_thread::sleep_for(std::chrono::seconds(1)); //allow for some setup time + std::this_thread::sleep_for(std::chrono::seconds(1)); // allow for some setup time - //for the const wave, set the wave freq for small samples per period - if (wave_freq == 0){ - if (wave_type == "CONST"){ - wave_freq = usrp->get_tx_rate()/2; + // for the const wave, set the wave freq for small samples per period + if (wave_freq == 0) { + if (wave_type == "CONST") { + wave_freq = usrp->get_tx_rate() / 2; } else { - throw std::runtime_error("wave freq cannot be 0 with wave type other than CONST"); + throw std::runtime_error( + "wave freq cannot be 0 with wave type other than CONST"); } } - //error when the waveform is not possible to generate - if (std::abs(wave_freq) > usrp->get_tx_rate()/2){ + // error when the waveform is not possible to generate + if (std::abs(wave_freq) > usrp->get_tx_rate() / 2) { throw std::runtime_error("wave freq out of Nyquist zone"); } - if (usrp->get_tx_rate()/std::abs(wave_freq) > wave_table_len/2){ + if (usrp->get_tx_rate() / std::abs(wave_freq) > wave_table_len / 2) { throw std::runtime_error("wave freq too small for table"); } - //pre-compute the waveform values + // pre-compute the waveform values const wave_table_class wave_table(wave_type, ampl); - const size_t step = boost::math::iround(wave_freq/usrp->get_tx_rate() * wave_table_len); + const size_t step = + boost::math::iround(wave_freq / usrp->get_tx_rate() * wave_table_len); size_t index = 0; - //create a transmit streamer - //linearly map channels (index0 = channel0, index1 = channel1, ...) + // create a transmit streamer + // linearly map channels (index0 = channel0, index1 = channel1, ...) uhd::stream_args_t stream_args("fc32", otw); - stream_args.channels = channel_nums; + stream_args.channels = channel_nums; uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //allocate a buffer which we re-use for each channel + // allocate a buffer which we re-use for each channel if (spb == 0) { - spb = tx_stream->get_max_num_samps()*10; + spb = tx_stream->get_max_num_samps() * 10; } - std::vector<std::complex<float> > buff(spb); - std::vector<std::complex<float> *> buffs(channel_nums.size(), &buff.front()); + std::vector<std::complex<float>> buff(spb); + std::vector<std::complex<float>*> buffs(channel_nums.size(), &buff.front()); - //pre-fill the buffer with the waveform - for (size_t n = 0; n < buff.size(); n++){ + // pre-fill the buffer with the waveform + for (size_t n = 0; n < buff.size(); n++) { buff[n] = wave_table(index += step); } std::cout << boost::format("Setting device timestamp to 0...") << std::endl; - if (channel_nums.size() > 1) - { + if (channel_nums.size() > 1) { // Sync times - if (pps == "mimo") - { + if (pps == "mimo") { UHD_ASSERT_THROW(usrp->get_num_mboards() == 2); - //make mboard 1 a slave over the MIMO Cable + // make mboard 1 a slave over the MIMO Cable usrp->set_time_source("mimo", 1); - //set time on the master (mboard 0) + // set time on the master (mboard 0) usrp->set_time_now(uhd::time_spec_t(0.0), 0); - //sleep a bit while the slave locks its time to the master + // sleep a bit while the slave locks its time to the master std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - else - { + } else { if (pps == "internal" or pps == "external" or pps == "gpsdo") usrp->set_time_source(pps); usrp->set_time_unknown_pps(uhd::time_spec_t(0.0)); - std::this_thread::sleep_for(std::chrono::seconds(1)); //wait for pps sync pulse + std::this_thread::sleep_for( + std::chrono::seconds(1)); // wait for pps sync pulse } - } - else - { + } else { usrp->set_time_now(0.0); } - //Check Ref and LO Lock detect + // Check Ref and LO Lock detect std::vector<std::string> sensor_names; const size_t tx_sensor_chan = channel_nums.empty() ? 0 : channel_nums[0]; - sensor_names = usrp->get_tx_sensor_names(tx_sensor_chan); - if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { + sensor_names = usrp->get_tx_sensor_names(tx_sensor_chan); + if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") + != sensor_names.end()) { uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked", tx_sensor_chan); - std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl; + std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } const size_t mboard_sensor_idx = 0; - sensor_names = usrp->get_mboard_sensor_names(mboard_sensor_idx); - if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { - uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", mboard_sensor_idx); - std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl; + sensor_names = usrp->get_mboard_sensor_names(mboard_sensor_idx); + if ((ref == "mimo") + and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") + != sensor_names.end())) { + uhd::sensor_value_t mimo_locked = + usrp->get_mboard_sensor("mimo_locked", mboard_sensor_idx); + std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (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", mboard_sensor_idx); - std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (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", mboard_sensor_idx); + std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } @@ -249,13 +277,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ md.start_of_burst = true; md.end_of_burst = false; md.has_time_spec = true; - md.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.1); + md.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.1); - //send data until the signal handler gets called - //or if we accumulate the number of samples specified (unless it's 0) + // send data until the signal handler gets called + // or if we accumulate the number of samples specified (unless it's 0) uint64_t num_acc_samps = 0; - while(true){ - + while (true) { // Break on the end of duration or CTRL-C if (stop_signal_called) { break; @@ -265,25 +292,23 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ break; } - //send the entire contents of the buffer - num_acc_samps += tx_stream->send( - buffs, buff.size(), md - ); + // send the entire contents of the buffer + num_acc_samps += tx_stream->send(buffs, buff.size(), md); - //fill the buffer with the waveform - for (size_t n = 0; n < buff.size(); n++){ + // fill the buffer with the waveform + for (size_t n = 0; n < buff.size(); n++) { buff[n] = wave_table(index += step); } md.start_of_burst = false; - md.has_time_spec = false; + md.has_time_spec = false; } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; } diff --git a/host/examples/txrx_loopback_to_file.cpp b/host/examples/txrx_loopback_to_file.cpp index cae69e043..d1d0ae615 100644 --- a/host/examples/txrx_loopback_to_file.cpp +++ b/host/examples/txrx_loopback_to_file.cpp @@ -6,21 +6,21 @@ // #include "wavetable.hpp" +#include <uhd/exception.hpp> #include <uhd/types/tune_request.hpp> -#include <uhd/utils/thread.hpp> +#include <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/utils/static.hpp> -#include <uhd/usrp/multi_usrp.hpp> -#include <uhd/exception.hpp> -#include <boost/thread/thread.hpp> -#include <boost/program_options.hpp> -#include <boost/math/special_functions/round.hpp> -#include <boost/format.hpp> +#include <uhd/utils/thread.hpp> #include <boost/algorithm/string.hpp> #include <boost/filesystem.hpp> -#include <iostream> -#include <fstream> +#include <boost/format.hpp> +#include <boost/math/special_functions/round.hpp> +#include <boost/program_options.hpp> +#include <boost/thread/thread.hpp> #include <csignal> +#include <fstream> +#include <iostream> namespace po = boost::program_options; @@ -28,25 +28,26 @@ namespace po = boost::program_options; * Signal handlers **********************************************************************/ static bool stop_signal_called = false; -void sig_int_handler(int){stop_signal_called = true;} +void sig_int_handler(int) +{ + stop_signal_called = true; +} /*********************************************************************** * Utilities **********************************************************************/ //! Change to filename, e.g. from usrp_samples.dat to usrp_samples.00.dat, // but only if multiple names are to be generated. -std::string generate_out_filename(const std::string &base_fn, size_t n_names, size_t this_name) +std::string generate_out_filename( + const std::string& base_fn, size_t n_names, size_t this_name) { if (n_names == 1) { return base_fn; } boost::filesystem::path base_fn_fp(base_fn); - base_fn_fp.replace_extension( - boost::filesystem::path( - str(boost::format("%02d%s") % this_name % base_fn_fp.extension().string()) - ) - ); + base_fn_fp.replace_extension(boost::filesystem::path( + str(boost::format("%02d%s") % this_name % base_fn_fp.extension().string()))); return base_fn_fp.string(); } @@ -55,32 +56,31 @@ std::string generate_out_filename(const std::string &base_fn, size_t n_names, si * transmit_worker function * A function to be used as a boost::thread_group thread for transmitting **********************************************************************/ -void transmit_worker( - std::vector<std::complex<float> > buff, +void transmit_worker(std::vector<std::complex<float>> buff, wave_table_class wave_table, uhd::tx_streamer::sptr tx_streamer, uhd::tx_metadata_t metadata, size_t step, size_t index, - int num_channels -){ - std::vector<std::complex<float> *> buffs(num_channels, &buff.front()); - - //send data until the signal handler gets called - while(not stop_signal_called){ - //fill the buffer with the waveform - for (size_t n = 0; n < buff.size(); n++){ + int num_channels) +{ + std::vector<std::complex<float>*> buffs(num_channels, &buff.front()); + + // send data until the signal handler gets called + while (not stop_signal_called) { + // fill the buffer with the waveform + for (size_t n = 0; n < buff.size(); n++) { buff[n] = wave_table(index += step); } - //send the entire contents of the buffer + // send the entire contents of the buffer tx_streamer->send(buffs, buff.size(), metadata); metadata.start_of_burst = false; - metadata.has_time_spec = false; + metadata.has_time_spec = false; } - //send a mini EOB packet + // send a mini EOB packet metadata.end_of_burst = true; tx_streamer->send("", 0, metadata); } @@ -89,86 +89,88 @@ void transmit_worker( /*********************************************************************** * recv_to_file function **********************************************************************/ -template<typename samp_type> void recv_to_file( - uhd::usrp::multi_usrp::sptr usrp, - const std::string &cpu_format, - const std::string &wire_format, - const std::string &file, +template <typename samp_type> +void recv_to_file(uhd::usrp::multi_usrp::sptr usrp, + const std::string& cpu_format, + const std::string& wire_format, + const std::string& file, size_t samps_per_buff, int num_requested_samples, double settling_time, - std::vector<size_t> rx_channel_nums -){ + std::vector<size_t> rx_channel_nums) +{ int num_total_samps = 0; - //create a receive streamer - uhd::stream_args_t stream_args(cpu_format,wire_format); - stream_args.channels = rx_channel_nums; + // create a receive streamer + uhd::stream_args_t stream_args(cpu_format, wire_format); + stream_args.channels = rx_channel_nums; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); // Prepare buffers for received samples and metadata uhd::rx_metadata_t md; - std::vector <std::vector< samp_type > > buffs( - rx_channel_nums.size(), std::vector< samp_type >(samps_per_buff) - ); - //create a vector of pointers to point to each of the channel buffers - std::vector<samp_type *> buff_ptrs; + std::vector<std::vector<samp_type>> buffs( + rx_channel_nums.size(), std::vector<samp_type>(samps_per_buff)); + // create a vector of pointers to point to each of the channel buffers + std::vector<samp_type*> buff_ptrs; for (size_t i = 0; i < buffs.size(); i++) { buff_ptrs.push_back(&buffs[i].front()); } // Create one ofstream object per channel // (use shared_ptr because ofstream is non-copyable) - std::vector<boost::shared_ptr<std::ofstream> > outfiles; + std::vector<boost::shared_ptr<std::ofstream>> outfiles; for (size_t i = 0; i < buffs.size(); i++) { const std::string this_filename = generate_out_filename(file, buffs.size(), i); - outfiles.push_back(boost::shared_ptr<std::ofstream>(new std::ofstream(this_filename.c_str(), std::ofstream::binary))); + outfiles.push_back(boost::shared_ptr<std::ofstream>( + new std::ofstream(this_filename.c_str(), std::ofstream::binary))); } UHD_ASSERT_THROW(outfiles.size() == buffs.size()); UHD_ASSERT_THROW(buffs.size() == rx_channel_nums.size()); bool overflow_message = true; - double timeout = settling_time + 0.1f; //expected settling time + padding for first recv - - //setup streaming - uhd::stream_cmd_t stream_cmd((num_requested_samples == 0)? - uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS: - uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE - ); - stream_cmd.num_samps = num_requested_samples; + double timeout = + settling_time + 0.1f; // expected settling time + padding for first recv + + // setup streaming + uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) + ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS + : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = num_requested_samples; stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(settling_time); + stream_cmd.time_spec = uhd::time_spec_t(settling_time); rx_stream->issue_stream_cmd(stream_cmd); - while(not stop_signal_called and (num_requested_samples > num_total_samps or num_requested_samples == 0)){ + while (not stop_signal_called + and (num_requested_samples > num_total_samps or num_requested_samples == 0)) { size_t num_rx_samps = rx_stream->recv(buff_ptrs, samps_per_buff, md, timeout); - timeout = 0.1f; //small timeout for subsequent recv + timeout = 0.1f; // small timeout for subsequent recv if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { std::cout << boost::format("Timeout while streaming") << std::endl; break; } - if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW){ - if (overflow_message){ + if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { + if (overflow_message) { overflow_message = false; - std::cerr << boost::format( - "Got an overflow indication. Please consider the following:\n" - " Your write medium must sustain a rate of %fMB/s.\n" - " Dropped samples will not be written to the file.\n" - " Please modify this example for your purposes.\n" - " This message will not appear again.\n" - ) % (usrp->get_rx_rate()*sizeof(samp_type)/1e6); + std::cerr + << boost::format( + "Got an overflow indication. Please consider the following:\n" + " Your write medium must sustain a rate of %fMB/s.\n" + " Dropped samples will not be written to the file.\n" + " Please modify this example for your purposes.\n" + " This message will not appear again.\n") + % (usrp->get_rx_rate() * sizeof(samp_type) / 1e6); } continue; } - 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())); } num_total_samps += num_rx_samps; for (size_t i = 0; i < outfiles.size(); i++) { - outfiles[i]->write((const char*) buff_ptrs[i], num_rx_samps*sizeof(samp_type)); + outfiles[i]->write( + (const char*)buff_ptrs[i], num_rx_samps * sizeof(samp_type)); } } @@ -186,21 +188,22 @@ template<typename samp_type> void recv_to_file( /*********************************************************************** * Main function **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ uhd::set_thread_priority_safe(); - //transmit variables to be set by po + // transmit variables to be set by po std::string tx_args, wave_type, tx_ant, tx_subdev, ref, otw, tx_channels; double tx_rate, tx_freq, tx_gain, wave_freq, tx_bw; float ampl; - //receive variables to be set by po + // receive variables to be set by po std::string rx_args, file, type, rx_ant, rx_subdev, rx_channels; size_t total_num_samps, spb; double rx_rate, rx_freq, rx_gain, rx_bw; double settling; - //setup the program options + // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -239,245 +242,315 @@ 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 TXRX Loopback to File %s") % desc << std::endl; return ~0; } - //create a usrp device + // create a usrp device std::cout << std::endl; - std::cout << boost::format("Creating the transmit usrp device with: %s...") % tx_args << std::endl; + std::cout << boost::format("Creating the transmit usrp device with: %s...") % tx_args + << std::endl; uhd::usrp::multi_usrp::sptr tx_usrp = uhd::usrp::multi_usrp::make(tx_args); std::cout << std::endl; - std::cout << boost::format("Creating the receive usrp device with: %s...") % rx_args << std::endl; + std::cout << boost::format("Creating the receive usrp device with: %s...") % rx_args + << std::endl; uhd::usrp::multi_usrp::sptr rx_usrp = uhd::usrp::multi_usrp::make(rx_args); - //always select the subdevice first, the channel mapping affects the other settings - if (vm.count("tx-subdev")) tx_usrp->set_tx_subdev_spec(tx_subdev); - if (vm.count("rx-subdev")) rx_usrp->set_rx_subdev_spec(rx_subdev); + // always select the subdevice first, the channel mapping affects the other settings + if (vm.count("tx-subdev")) + tx_usrp->set_tx_subdev_spec(tx_subdev); + if (vm.count("rx-subdev")) + rx_usrp->set_rx_subdev_spec(rx_subdev); - //detect which channels to use + // detect which channels to use std::vector<std::string> tx_channel_strings; std::vector<size_t> tx_channel_nums; boost::split(tx_channel_strings, tx_channels, boost::is_any_of("\"',")); - for(size_t ch = 0; ch < tx_channel_strings.size(); ch++){ + for (size_t ch = 0; ch < tx_channel_strings.size(); ch++) { size_t chan = std::stoi(tx_channel_strings[ch]); - if(chan >= tx_usrp->get_tx_num_channels()){ + if (chan >= tx_usrp->get_tx_num_channels()) { throw std::runtime_error("Invalid TX channel(s) specified."); - } - else tx_channel_nums.push_back(std::stoi(tx_channel_strings[ch])); + } else + tx_channel_nums.push_back(std::stoi(tx_channel_strings[ch])); } std::vector<std::string> rx_channel_strings; std::vector<size_t> rx_channel_nums; boost::split(rx_channel_strings, rx_channels, boost::is_any_of("\"',")); - for(size_t ch = 0; ch < rx_channel_strings.size(); ch++){ + for (size_t ch = 0; ch < rx_channel_strings.size(); ch++) { size_t chan = std::stoi(rx_channel_strings[ch]); - if(chan >= rx_usrp->get_rx_num_channels()){ + if (chan >= rx_usrp->get_rx_num_channels()) { throw std::runtime_error("Invalid RX channel(s) specified."); - } - else rx_channel_nums.push_back(std::stoi(rx_channel_strings[ch])); + } else + rx_channel_nums.push_back(std::stoi(rx_channel_strings[ch])); } - //Lock mboard clocks + // Lock mboard clocks tx_usrp->set_clock_source(ref); rx_usrp->set_clock_source(ref); - std::cout << boost::format("Using TX Device: %s") % tx_usrp->get_pp_string() << std::endl; - std::cout << boost::format("Using RX Device: %s") % rx_usrp->get_pp_string() << std::endl; + std::cout << boost::format("Using TX Device: %s") % tx_usrp->get_pp_string() + << std::endl; + std::cout << boost::format("Using RX Device: %s") % rx_usrp->get_pp_string() + << std::endl; - //set the transmit sample rate - if (not vm.count("tx-rate")){ - std::cerr << "Please specify the transmit sample rate with --tx-rate" << std::endl; + // set the transmit sample rate + if (not vm.count("tx-rate")) { + std::cerr << "Please specify the transmit sample rate with --tx-rate" + << std::endl; return ~0; } - std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl; + std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate / 1e6) + << std::endl; tx_usrp->set_tx_rate(tx_rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (tx_usrp->get_tx_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") + % (tx_usrp->get_tx_rate() / 1e6) + << std::endl + << std::endl; - //set the receive sample rate - if (not vm.count("rx-rate")){ + // set the receive sample rate + if (not vm.count("rx-rate")) { std::cerr << "Please specify the sample rate with --rx-rate" << std::endl; return ~0; } - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate / 1e6) + << std::endl; rx_usrp->set_rx_rate(rx_rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (rx_usrp->get_rx_rate()/1e6) << std::endl << std::endl; - - //set the transmit center frequency - if (not vm.count("tx-freq")){ - std::cerr << "Please specify the transmit center frequency with --tx-freq" << std::endl; + std::cout << boost::format("Actual RX Rate: %f Msps...") + % (rx_usrp->get_rx_rate() / 1e6) + << std::endl + << std::endl; + + // set the transmit center frequency + if (not vm.count("tx-freq")) { + std::cerr << "Please specify the transmit center frequency with --tx-freq" + << std::endl; return ~0; } - for(size_t ch = 0; ch < tx_channel_nums.size(); ch++) { + for (size_t ch = 0; ch < tx_channel_nums.size(); ch++) { size_t channel = tx_channel_nums[ch]; if (tx_channel_nums.size() > 1) { std::cout << "Configuring TX Channel " << channel << std::endl; } - std::cout << boost::format("Setting TX Freq: %f MHz...") % (tx_freq/1e6) << std::endl; + std::cout << boost::format("Setting TX Freq: %f MHz...") % (tx_freq / 1e6) + << std::endl; uhd::tune_request_t tx_tune_request(tx_freq); - if(vm.count("tx-int-n")) tx_tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("tx-int-n")) + tx_tune_request.args = uhd::device_addr_t("mode_n=integer"); tx_usrp->set_tx_freq(tx_tune_request, channel); - std::cout << boost::format("Actual TX Freq: %f MHz...") % (tx_usrp->get_tx_freq(channel)/1e6) << std::endl << std::endl; - - //set the rf gain - if (vm.count("tx-gain")){ - std::cout << boost::format("Setting TX Gain: %f dB...") % tx_gain << std::endl; + std::cout << boost::format("Actual TX Freq: %f MHz...") + % (tx_usrp->get_tx_freq(channel) / 1e6) + << std::endl + << std::endl; + + // set the rf gain + if (vm.count("tx-gain")) { + std::cout << boost::format("Setting TX Gain: %f dB...") % tx_gain + << std::endl; tx_usrp->set_tx_gain(tx_gain, channel); - std::cout << boost::format("Actual TX Gain: %f dB...") % tx_usrp->get_tx_gain(channel) << std::endl << std::endl; + std::cout << boost::format("Actual TX Gain: %f dB...") + % tx_usrp->get_tx_gain(channel) + << std::endl + << std::endl; } - //set the analog frontend filter bandwidth - if (vm.count("tx-bw")){ - std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % tx_bw << std::endl; + // set the analog frontend filter bandwidth + if (vm.count("tx-bw")) { + std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % tx_bw + << std::endl; tx_usrp->set_tx_bandwidth(tx_bw, channel); - std::cout << boost::format("Actual TX Bandwidth: %f MHz...") % tx_usrp->get_tx_bandwidth(channel) << std::endl << std::endl; + std::cout << boost::format("Actual TX Bandwidth: %f MHz...") + % tx_usrp->get_tx_bandwidth(channel) + << std::endl + << std::endl; } - //set the antenna - if (vm.count("tx-ant")) tx_usrp->set_tx_antenna(tx_ant, channel); + // set the antenna + if (vm.count("tx-ant")) + tx_usrp->set_tx_antenna(tx_ant, channel); } - for(size_t ch = 0; ch < rx_channel_nums.size(); ch++) { + for (size_t ch = 0; ch < rx_channel_nums.size(); ch++) { size_t channel = rx_channel_nums[ch]; if (rx_channel_nums.size() > 1) { std::cout << "Configuring RX Channel " << channel << std::endl; } - //set the receive center frequency - if (not vm.count("rx-freq")){ - std::cerr << "Please specify the center frequency with --rx-freq" << std::endl; + // set the receive center frequency + if (not vm.count("rx-freq")) { + std::cerr << "Please specify the center frequency with --rx-freq" + << std::endl; return ~0; } - std::cout << boost::format("Setting RX Freq: %f MHz...") % (rx_freq/1e6) << std::endl; + std::cout << boost::format("Setting RX Freq: %f MHz...") % (rx_freq / 1e6) + << std::endl; uhd::tune_request_t rx_tune_request(rx_freq); - if(vm.count("rx-int-n")) rx_tune_request.args = uhd::device_addr_t("mode_n=integer"); + if (vm.count("rx-int-n")) + rx_tune_request.args = uhd::device_addr_t("mode_n=integer"); rx_usrp->set_rx_freq(rx_tune_request, channel); - std::cout << boost::format("Actual RX Freq: %f MHz...") % (rx_usrp->get_rx_freq(channel)/1e6) << std::endl << std::endl; - - //set the receive rf gain - if (vm.count("rx-gain")){ - std::cout << boost::format("Setting RX Gain: %f dB...") % rx_gain << std::endl; + std::cout << boost::format("Actual RX Freq: %f MHz...") + % (rx_usrp->get_rx_freq(channel) / 1e6) + << std::endl + << std::endl; + + // set the receive rf gain + if (vm.count("rx-gain")) { + std::cout << boost::format("Setting RX Gain: %f dB...") % rx_gain + << std::endl; rx_usrp->set_rx_gain(rx_gain, channel); - std::cout << boost::format("Actual RX Gain: %f dB...") % rx_usrp->get_rx_gain(channel) << std::endl << std::endl; + std::cout << boost::format("Actual RX Gain: %f dB...") + % rx_usrp->get_rx_gain(channel) + << std::endl + << std::endl; } - //set the receive analog frontend filter bandwidth - if (vm.count("rx-bw")){ - std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (rx_bw/1e6) << std::endl; + // set the receive analog frontend filter bandwidth + if (vm.count("rx-bw")) { + std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (rx_bw / 1e6) + << std::endl; rx_usrp->set_rx_bandwidth(rx_bw, channel); - std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (rx_usrp->get_rx_bandwidth(channel)/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual RX Bandwidth: %f MHz...") + % (rx_usrp->get_rx_bandwidth(channel) / 1e6) + << std::endl + << std::endl; } // set the receive antenna - if (vm.count("rx-ant")) rx_usrp->set_rx_antenna(rx_ant, channel); + if (vm.count("rx-ant")) + rx_usrp->set_rx_antenna(rx_ant, channel); } - //for the const wave, set the wave freq for small samples per period - if (wave_freq == 0 and wave_type == "CONST"){ - wave_freq = tx_usrp->get_tx_rate()/2; + // for the const wave, set the wave freq for small samples per period + if (wave_freq == 0 and wave_type == "CONST") { + wave_freq = tx_usrp->get_tx_rate() / 2; } - //error when the waveform is not possible to generate - if (std::abs(wave_freq) > tx_usrp->get_tx_rate()/2){ + // error when the waveform is not possible to generate + if (std::abs(wave_freq) > tx_usrp->get_tx_rate() / 2) { throw std::runtime_error("wave freq out of Nyquist zone"); } - if (tx_usrp->get_tx_rate()/std::abs(wave_freq) > wave_table_len/2){ + if (tx_usrp->get_tx_rate() / std::abs(wave_freq) > wave_table_len / 2) { throw std::runtime_error("wave freq too small for table"); } - //pre-compute the waveform values + // pre-compute the waveform values const wave_table_class wave_table(wave_type, ampl); - const size_t step = boost::math::iround(wave_freq/tx_usrp->get_tx_rate() * wave_table_len); + const size_t step = + boost::math::iround(wave_freq / tx_usrp->get_tx_rate() * wave_table_len); size_t index = 0; - //create a transmit streamer - //linearly map channels (index0 = channel0, index1 = channel1, ...) + // create a transmit streamer + // linearly map channels (index0 = channel0, index1 = channel1, ...) uhd::stream_args_t stream_args("fc32", otw); - stream_args.channels = tx_channel_nums; + stream_args.channels = tx_channel_nums; uhd::tx_streamer::sptr tx_stream = tx_usrp->get_tx_stream(stream_args); - //allocate a buffer which we re-use for each channel - if (spb == 0) spb = tx_stream->get_max_num_samps()*10; - std::vector<std::complex<float> > buff(spb); + // allocate a buffer which we re-use for each channel + if (spb == 0) + spb = tx_stream->get_max_num_samps() * 10; + std::vector<std::complex<float>> buff(spb); int num_channels = tx_channel_nums.size(); - //setup the metadata flags + // setup the metadata flags uhd::tx_metadata_t md; md.start_of_burst = true; md.end_of_burst = false; md.has_time_spec = true; - md.time_spec = uhd::time_spec_t(0.5); //give us 0.5 seconds to fill the tx buffers + md.time_spec = uhd::time_spec_t(0.5); // give us 0.5 seconds to fill the tx buffers - //Check Ref and LO Lock detect + // Check Ref and LO Lock detect std::vector<std::string> tx_sensor_names, rx_sensor_names; tx_sensor_names = tx_usrp->get_tx_sensor_names(0); - if (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "lo_locked") != tx_sensor_names.end()) { - uhd::sensor_value_t lo_locked = tx_usrp->get_tx_sensor("lo_locked",0); - std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl; + if (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "lo_locked") + != tx_sensor_names.end()) { + uhd::sensor_value_t lo_locked = tx_usrp->get_tx_sensor("lo_locked", 0); + std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } rx_sensor_names = rx_usrp->get_rx_sensor_names(0); - if (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "lo_locked") != rx_sensor_names.end()) { - uhd::sensor_value_t lo_locked = rx_usrp->get_rx_sensor("lo_locked",0); - std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() << std::endl; + if (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "lo_locked") + != rx_sensor_names.end()) { + uhd::sensor_value_t lo_locked = rx_usrp->get_rx_sensor("lo_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } tx_sensor_names = tx_usrp->get_mboard_sensor_names(0); - if ((ref == "mimo") and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "mimo_locked") != tx_sensor_names.end())) { - uhd::sensor_value_t mimo_locked = tx_usrp->get_mboard_sensor("mimo_locked",0); - std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl; + if ((ref == "mimo") + and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "mimo_locked") + != tx_sensor_names.end())) { + uhd::sensor_value_t mimo_locked = tx_usrp->get_mboard_sensor("mimo_locked", 0); + std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "ref_locked") != tx_sensor_names.end())) { - uhd::sensor_value_t ref_locked = tx_usrp->get_mboard_sensor("ref_locked",0); - std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "ref_locked") + != tx_sensor_names.end())) { + uhd::sensor_value_t ref_locked = tx_usrp->get_mboard_sensor("ref_locked", 0); + std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } rx_sensor_names = rx_usrp->get_mboard_sensor_names(0); - if ((ref == "mimo") and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "mimo_locked") != rx_sensor_names.end())) { - uhd::sensor_value_t mimo_locked = rx_usrp->get_mboard_sensor("mimo_locked",0); - std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() << std::endl; + if ((ref == "mimo") + and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "mimo_locked") + != rx_sensor_names.end())) { + uhd::sensor_value_t mimo_locked = rx_usrp->get_mboard_sensor("mimo_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } - if ((ref == "external") and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "ref_locked") != rx_sensor_names.end())) { - uhd::sensor_value_t ref_locked = rx_usrp->get_mboard_sensor("ref_locked",0); - std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() << std::endl; + if ((ref == "external") + and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "ref_locked") + != rx_sensor_names.end())) { + uhd::sensor_value_t ref_locked = rx_usrp->get_mboard_sensor("ref_locked", 0); + std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() + << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } - if (total_num_samps == 0){ + if (total_num_samps == 0) { std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; } - //reset usrp time to prepare for transmit/receive + // reset usrp time to prepare for transmit/receive std::cout << boost::format("Setting device timestamp to 0...") << std::endl; tx_usrp->set_time_now(uhd::time_spec_t(0.0)); - //start transmit worker thread + // start transmit worker thread boost::thread_group transmit_thread; - transmit_thread.create_thread(boost::bind(&transmit_worker, buff, wave_table, tx_stream, md, step, index, num_channels)); - - //recv to file - if (type == "double") recv_to_file<std::complex<double> >(rx_usrp, "fc64", otw, file, spb, total_num_samps, settling, rx_channel_nums); - else if (type == "float") recv_to_file<std::complex<float> >(rx_usrp, "fc32", otw, file, spb, total_num_samps, settling, rx_channel_nums); - else if (type == "short") recv_to_file<std::complex<short> >(rx_usrp, "sc16", otw, file, spb, total_num_samps, settling, rx_channel_nums); + transmit_thread.create_thread(boost::bind( + &transmit_worker, buff, wave_table, tx_stream, md, step, index, num_channels)); + + // recv to file + if (type == "double") + recv_to_file<std::complex<double>>( + rx_usrp, "fc64", otw, file, spb, total_num_samps, settling, rx_channel_nums); + else if (type == "float") + recv_to_file<std::complex<float>>( + rx_usrp, "fc32", otw, file, spb, total_num_samps, settling, rx_channel_nums); + else if (type == "short") + recv_to_file<std::complex<short>>( + rx_usrp, "sc16", otw, file, spb, total_num_samps, settling, rx_channel_nums); else { - //clean up transmit worker + // clean up transmit worker stop_signal_called = true; transmit_thread.join_all(); throw std::runtime_error("Unknown type " + type); } - //clean up transmit worker + // clean up transmit worker stop_signal_called = true; transmit_thread.join_all(); - //finished + // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; } diff --git a/host/examples/usrp_list_sensors.cpp b/host/examples/usrp_list_sensors.cpp index 0ffe33e5a..56ecf9b7a 100644 --- a/host/examples/usrp_list_sensors.cpp +++ b/host/examples/usrp_list_sensors.cpp @@ -6,60 +6,53 @@ #include <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/safe_main.hpp> -#include <boost/program_options.hpp> #include <boost/algorithm/string.hpp> //for split +#include <boost/program_options.hpp> #include <iostream> #include <sstream> namespace po = boost::program_options; namespace { - std::string make_border(const std::string &text) - { - std::stringstream ss; - ss << " _____________________________________________________\n"; - ss << " /" << 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 (not lines.empty()) { - lines[0] = " " + lines[0]; //indent the title line - } - for (const std::string& line : lines) - { - ss << "| " << line << std::endl; - } - return ss.str(); +std::string make_border(const std::string& text) +{ + std::stringstream ss; + ss << " _____________________________________________________\n"; + ss << " /" << 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 (not lines.empty()) { + lines[0] = " " + lines[0]; // indent the title line } + for (const std::string& line : lines) { + ss << "| " << line << std::endl; + } + return ss.str(); } +} // namespace using namespace uhd::usrp; std::string db_sensors_string( - const std::string& tx_rx, - multi_usrp::sptr usrp, - const size_t mb_idx -) { + const std::string& tx_rx, multi_usrp::sptr usrp, const size_t mb_idx) +{ std::stringstream ss; ss << tx_rx << " Sensors: \n" << std::endl; - const size_t num_chans = (tx_rx == "RX") - ? usrp->get_rx_subdev_spec(mb_idx).size() - : usrp->get_tx_subdev_spec(mb_idx).size() - ; + const size_t num_chans = (tx_rx == "RX") ? usrp->get_rx_subdev_spec(mb_idx).size() + : usrp->get_tx_subdev_spec(mb_idx).size(); for (size_t chan_idx = 0; chan_idx < num_chans; chan_idx++) { ss << "Chan " << chan_idx << ": " << std::endl; - const auto sensors = (tx_rx == "RX") - ? usrp->get_rx_sensor_names(chan_idx) - : usrp->get_tx_sensor_names(chan_idx); + const auto sensors = (tx_rx == "RX") ? usrp->get_rx_sensor_names(chan_idx) + : usrp->get_tx_sensor_names(chan_idx); for (const auto& sensor : sensors) { const auto sensor_value = (tx_rx == "RX") - ? usrp->get_rx_sensor(sensor, chan_idx) - : usrp->get_tx_sensor(sensor, chan_idx) - ; + ? usrp->get_rx_sensor(sensor, chan_idx) + : usrp->get_tx_sensor(sensor, chan_idx); ss << "* " << sensor_value.to_pp_string() << std::endl; } ss << std::endl; @@ -74,8 +67,7 @@ std::string mboard_sensors_string(multi_usrp::sptr usrp, const size_t mb_idx) ss << "Sensors for motherboard " << mb_idx << ": \n" << std::endl; const auto mboard_sensors = usrp->get_mboard_sensor_names(mb_idx); for (const auto& mboard_sensor : mboard_sensors) { - const auto sensor_value = - usrp->get_mboard_sensor(mboard_sensor, mb_idx); + const auto sensor_value = usrp->get_mboard_sensor(mboard_sensor, mb_idx); ss << "* " << sensor_value.to_pp_string() << std::endl; } ss << make_border(db_sensors_string("RX", usrp, mb_idx)) << std::endl; @@ -84,8 +76,8 @@ std::string mboard_sensors_string(multi_usrp::sptr usrp, const size_t mb_idx) return ss.str(); } -int UHD_SAFE_MAIN(int argc, char *argv[]){ - +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ // Variables to be set by command line options std::string usrp_args; @@ -102,11 +94,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::notify(vm); // Print the help message - if (vm.count("help")){ - std::cout << std::endl << "Print sensor values" - << std::endl << std::endl; + if (vm.count("help")) { + std::cout << std::endl << "Print sensor values" << std::endl << std::endl; std::cout << "This example shows how to query sensors from" - << "a USRP device.\n" << std::endl; + << "a USRP device.\n" + << std::endl; std::cout << desc << std::endl; return EXIT_SUCCESS; } @@ -116,12 +108,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ multi_usrp::sptr usrp = multi_usrp::make(usrp_args); const size_t num_mboards = usrp->get_num_mboards(); - std::cout << "Device contains " << num_mboards - << " motherboard(s)." << std::endl << std::endl; + std::cout << "Device contains " << num_mboards << " motherboard(s)." << std::endl + << std::endl; for (size_t mboard_idx = 0; mboard_idx < num_mboards; mboard_idx++) { - std::cout << make_border(mboard_sensors_string(usrp, mboard_idx)) - << std::endl; + std::cout << make_border(mboard_sensors_string(usrp, mboard_idx)) << std::endl; } return EXIT_SUCCESS; diff --git a/host/examples/wavetable.hpp b/host/examples/wavetable.hpp index 8fdc8db30..2a1d13f48 100644 --- a/host/examples/wavetable.hpp +++ b/host/examples/wavetable.hpp @@ -5,55 +5,51 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <string> #include <cmath> #include <complex> -#include <vector> #include <stdexcept> +#include <string> +#include <vector> static const size_t wave_table_len = 8192; -class wave_table_class{ +class wave_table_class +{ public: - wave_table_class(const std::string &wave_type, const float ampl): - _wave_table(wave_table_len) + wave_table_class(const std::string& wave_type, const float ampl) + : _wave_table(wave_table_len) { - //compute real wave table with 1.0 amplitude + // compute real wave table with 1.0 amplitude std::vector<float> real_wave_table(wave_table_len); - if (wave_type == "CONST"){ + if (wave_type == "CONST") { for (size_t i = 0; i < wave_table_len; i++) real_wave_table[i] = 1.0; - } - else if (wave_type == "SQUARE"){ + } else if (wave_type == "SQUARE") { for (size_t i = 0; i < wave_table_len; i++) - real_wave_table[i] = (i < wave_table_len/2)? 0.0 : 1.0; - } - else if (wave_type == "RAMP"){ + real_wave_table[i] = (i < wave_table_len / 2) ? 0.0 : 1.0; + } else if (wave_type == "RAMP") { for (size_t i = 0; i < wave_table_len; i++) - real_wave_table[i] = 2.0*i/(wave_table_len-1) - 1.0; - } - else if (wave_type == "SINE"){ - static const double tau = 2*std::acos(-1.0); + real_wave_table[i] = 2.0 * i / (wave_table_len - 1) - 1.0; + } else if (wave_type == "SINE") { + static const double tau = 2 * std::acos(-1.0); for (size_t i = 0; i < wave_table_len; i++) - real_wave_table[i] = std::sin((tau*i)/wave_table_len); - } - else throw std::runtime_error("unknown waveform type: " + wave_type); + real_wave_table[i] = std::sin((tau * i) / wave_table_len); + } else + throw std::runtime_error("unknown waveform type: " + wave_type); - //compute i and q pairs with 90% offset and scale to amplitude - for (size_t i = 0; i < wave_table_len; i++){ - const size_t q = (i+(3*wave_table_len)/4)%wave_table_len; - _wave_table[i] = std::complex<float>( - ampl*real_wave_table[i], - ampl*real_wave_table[q] - ); + // compute i and q pairs with 90% offset and scale to amplitude + for (size_t i = 0; i < wave_table_len; i++) { + const size_t q = (i + (3 * wave_table_len) / 4) % wave_table_len; + _wave_table[i] = + std::complex<float>(ampl * real_wave_table[i], ampl * real_wave_table[q]); } } - inline std::complex<float> operator()(const size_t index) const{ + inline std::complex<float> operator()(const size_t index) const + { return _wave_table[index % wave_table_len]; } private: - std::vector<std::complex<float> > _wave_table; + std::vector<std::complex<float>> _wave_table; }; - |