diff options
author | Brent Stapleton <brent.stapleton@ettus.com> | 2019-01-14 10:35:25 -0800 |
---|---|---|
committer | Brent Stapleton <brent.stapleton@ettus.com> | 2019-01-16 11:40:23 -0800 |
commit | 967be2a4e82b1a125b26bb72a60318a4fb2b50c4 (patch) | |
tree | 8a24954b54d1546dc8049a17e485adb0a605f74f /host | |
parent | aafe4e8b742a0e21d3818f21f34e3c8613132530 (diff) | |
download | uhd-967be2a4e82b1a125b26bb72a60318a4fb2b50c4.tar.gz uhd-967be2a4e82b1a125b26bb72a60318a4fb2b50c4.tar.bz2 uhd-967be2a4e82b1a125b26bb72a60318a4fb2b50c4.zip |
uhd: mpm: apply clang-format to all files
Applying formatting changes to all .cpp and .hpp files in the following
directories:
```
find host/examples/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/tests/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/dboard/neon/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/dboard/magnesium/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/device3/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/mpmd/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/x300/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/utils/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find mpm/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
```
Also formatted host/include/, except Cpp03 was used as a the language
standard instead of Cpp11.
```
sed -i 's/ Cpp11/ Cpp03/g' .clang-format
find host/include/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
```
Formatting style was designated by the .clang-format file.
Diffstat (limited to 'host')
279 files changed, 20150 insertions, 20123 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; }; - diff --git a/host/include/uhd/build_info.hpp b/host/include/uhd/build_info.hpp index 7bac2e89e..88de3ea27 100644 --- a/host/include/uhd/build_info.hpp +++ b/host/include/uhd/build_info.hpp @@ -8,37 +8,36 @@ #define INCLUDED_UHD_BUILD_INFO_HPP #include <uhd/config.hpp> - #include <string> namespace uhd { namespace build_info { - //! Return the version of Boost this build was built with. - UHD_API const std::string boost_version(); +//! Return the version of Boost this build was built with. +UHD_API const std::string boost_version(); - //! Return the date and time (GMT) this UHD build was built. - UHD_API const std::string build_date(); +//! Return the date and time (GMT) this UHD build was built. +UHD_API const std::string build_date(); - //! Return the C compiler used for this build. - UHD_API const std::string c_compiler(); +//! Return the C compiler used for this build. +UHD_API const std::string c_compiler(); - //! Return the C++ compiler used for this build. - UHD_API const std::string cxx_compiler(); +//! Return the C++ compiler used for this build. +UHD_API const std::string cxx_compiler(); - //! Return the C flags passed into this build. - UHD_API const std::string c_flags(); +//! Return the C flags passed into this build. +UHD_API const std::string c_flags(); - //! Return the C++ flags passed into this build. - UHD_API const std::string cxx_flags(); +//! Return the C++ flags passed into this build. +UHD_API const std::string cxx_flags(); - //! Return the UHD components enabled for this build, comma-delimited. - UHD_API const std::string enabled_components(); +//! Return the UHD components enabled for this build, comma-delimited. +UHD_API const std::string enabled_components(); - //! Return the default CMake install prefix for this build. - UHD_API const std::string install_prefix(); +//! Return the default CMake install prefix for this build. +UHD_API const std::string install_prefix(); - //! Return the version of libusb this build was built with. - UHD_API const std::string libusb_version(); -}} +//! Return the version of libusb this build was built with. +UHD_API const std::string libusb_version(); +}} // namespace uhd::build_info #endif /* INCLUDED_UHD_BUILD_INFO_HPP */ diff --git a/host/include/uhd/cal/container.hpp b/host/include/uhd/cal/container.hpp index 5e6c612d8..75ce566e2 100644 --- a/host/include/uhd/cal/container.hpp +++ b/host/include/uhd/cal/container.hpp @@ -9,18 +9,18 @@ #define INCLUDED_UHD_CAL_CONTAINER_HPP #include <uhd/config.hpp> -#include <boost/serialization/serialization.hpp> -#include <boost/serialization/vector.hpp> -#include <boost/serialization/string.hpp> -#include <boost/serialization/map.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> +#include <boost/serialization/map.hpp> +#include <boost/serialization/serialization.hpp> +#include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include <boost/shared_ptr.hpp> -namespace uhd { -namespace cal { +namespace uhd { namespace cal { -class base_container { +class base_container +{ public: typedef std::map<std::string, std::string> metadata_t; typedef boost::shared_ptr<base_container> sptr; @@ -37,8 +37,9 @@ public: * The container only supports inputs of the same type to be mapped. * */ -template<typename in_type, typename out_type> -class UHD_API cal_container : public base_container { +template <typename in_type, typename out_type> +class UHD_API cal_container : public base_container +{ public: typedef std::map<in_type, out_type> container_t; @@ -51,7 +52,7 @@ public: * \throws uhd::assertion_error if the dimensions of the input args * are incorrect for this container */ - virtual out_type get(const in_type &args) = 0; + virtual out_type get(const in_type& args) = 0; /*! * Add a data point to the container. @@ -61,21 +62,21 @@ public: * \param output the output of the data point mapping * \param args input values */ - virtual void add(const out_type output, const in_type &args) = 0; + virtual void add(const out_type output, const in_type& args) = 0; /*! * Associate some metadata with the container. * * \param data a map of metadata (string -> string). */ - virtual void add_metadata(const metadata_t &data) = 0; + virtual void add_metadata(const metadata_t& data) = 0; /*! * Retrieve metadata from the container. * * \returns map of metadata. */ - virtual const metadata_t &get_metadata() = 0; + virtual const metadata_t& get_metadata() = 0; public: typedef boost::archive::text_iarchive iarchive_type; @@ -84,11 +85,10 @@ public: protected: friend class boost::serialization::access; - virtual void serialize(iarchive_type & ar, const unsigned int) = 0; - virtual void serialize(oarchive_type & ar, const unsigned int) = 0; + virtual void serialize(iarchive_type& ar, const unsigned int) = 0; + virtual void serialize(oarchive_type& ar, const unsigned int) = 0; }; -} // namespace cal -} // namespace uhd +}} // namespace uhd::cal #endif /* INCLUDED_UHD_CAL_CONTAINER_HPP */ diff --git a/host/include/uhd/cal/power_container.hpp b/host/include/uhd/cal/power_container.hpp index 564a28018..052c68e6c 100644 --- a/host/include/uhd/cal/power_container.hpp +++ b/host/include/uhd/cal/power_container.hpp @@ -8,14 +8,14 @@ #ifndef INCLUDED_UHD_CAL_POWER_CONTAINER_HPP #define INCLUDED_UHD_CAL_POWER_CONTAINER_HPP -#include <uhd/config.hpp> #include <uhd/cal/container.hpp> +#include <uhd/config.hpp> #include <boost/shared_ptr.hpp> -namespace uhd { -namespace cal { +namespace uhd { namespace cal { -class UHD_API power_container : public cal_container<std::vector<double>, double> { +class UHD_API power_container : public cal_container<std::vector<double>, double> +{ public: typedef boost::shared_ptr<power_container> sptr; @@ -35,7 +35,7 @@ public: * \throws uhd::assertion_error if the number of input values are incorrect * for the container type */ - virtual double get(const std::vector<double> &args) = 0; + virtual double get(const std::vector<double>& args) = 0; /*! * Add a data point to the container. @@ -46,24 +46,23 @@ public: * \param output the output of the data point mapping * \param args input values */ - virtual void add(const double output, const std::vector<double> &args) = 0; + virtual void add(const double output, const std::vector<double>& args) = 0; /*! * Associate some metadata with the container. * * \param data a map of metadata (string -> string). */ - virtual void add_metadata(const metadata_t &data) = 0; + virtual void add_metadata(const metadata_t& data) = 0; /*! * Retrieve metadata from the container. * * \returns map of metadata. */ - virtual const metadata_t &get_metadata() = 0; + virtual const metadata_t& get_metadata() = 0; }; -} // namespace cal -} // namespace uhd +}} // namespace uhd::cal #endif /* INCLUDED_UHD_CAL_POWER_CONTAINER_HPP */ diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index e7b48e5d8..dee0716f4 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -18,99 +18,106 @@ //# pragma warning(disable: 4512) // assignment operator can't not be generated //# pragma warning(disable: 4100) // unreferenced formal parameter //# pragma warning(disable: 4996) // <symbol> was declared deprecated -# pragma warning(disable: 4355) // 'this' : used in base member initializer list +# pragma warning(disable : 4355) // 'this' : used in base member initializer list //# pragma warning(disable: 4706) // assignment within conditional expression -# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B' +# pragma warning(disable : 4251) // class 'A<T>' needs to have dll-interface to be used + // by clients of class 'B' //# pragma warning(disable: 4127) // conditional expression is constant //# pragma warning(disable: 4290) // C++ exception specification ignored except to ... -//# pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored -# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ... -//# pragma warning(disable: 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data -//# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated -# pragma warning(disable: 4250) // 'class' : inherits 'method' via dominance -# pragma warning(disable: 4200) // nonstandard extension used : zero-sized array in struct/union +//# pragma warning(disable: 4180) // qualifier applied to function type has no meaning; +// ignored +# pragma warning(disable : 4275) // non dll-interface class ... used as base for + // dll-interface class ... +//# pragma warning(disable: 4267) // 'var' : conversion from 'size_t' to 'type', possible +// loss of data # pragma warning(disable: 4511) // 'class' : copy constructor could not be +// generated +# pragma warning(disable : 4250) // 'class' : inherits 'method' via dominance +# pragma warning( \ + disable : 4200) // nonstandard extension used : zero-sized array in struct/union // define logical operators -#include <ciso646> +# include <ciso646> // define ssize_t -#include <cstddef> +# include <cstddef> typedef ptrdiff_t ssize_t; -#endif //BOOST_MSVC +#endif // BOOST_MSVC -//define cross platform attribute macros +// define cross platform attribute macros #if defined(BOOST_MSVC) - #define UHD_EXPORT __declspec(dllexport) - #define UHD_IMPORT __declspec(dllimport) - #define UHD_INLINE __forceinline - #define UHD_FORCE_INLINE __forceinline - #define UHD_DEPRECATED __declspec(deprecated) - #define UHD_ALIGNED(x) __declspec(align(x)) - #define UHD_UNUSED(x) x +# define UHD_EXPORT __declspec(dllexport) +# define UHD_IMPORT __declspec(dllimport) +# define UHD_INLINE __forceinline +# define UHD_FORCE_INLINE __forceinline +# define UHD_DEPRECATED __declspec(deprecated) +# define UHD_ALIGNED(x) __declspec(align(x)) +# define UHD_UNUSED(x) x #elif defined(__MINGW32__) - #define UHD_EXPORT __declspec(dllexport) - #define UHD_IMPORT __declspec(dllimport) - #define UHD_INLINE inline - #define UHD_FORCE_INLINE inline - #define UHD_DEPRECATED __declspec(deprecated) - #define UHD_ALIGNED(x) __declspec(align(x)) - #define UHD_UNUSED(x) x __attribute__((unused)) +# define UHD_EXPORT __declspec(dllexport) +# define UHD_IMPORT __declspec(dllimport) +# define UHD_INLINE inline +# define UHD_FORCE_INLINE inline +# define UHD_DEPRECATED __declspec(deprecated) +# define UHD_ALIGNED(x) __declspec(align(x)) +# define UHD_UNUSED(x) x __attribute__((unused)) #elif defined(__GNUG__) && __GNUG__ >= 4 - #define UHD_EXPORT __attribute__((visibility("default"))) - #define UHD_IMPORT __attribute__((visibility("default"))) - #define UHD_INLINE inline __attribute__((always_inline)) - #define UHD_FORCE_INLINE inline __attribute__((always_inline)) - #define UHD_DEPRECATED __attribute__((deprecated)) - #define UHD_ALIGNED(x) __attribute__((aligned(x))) - #define UHD_UNUSED(x) x __attribute__((unused)) +# define UHD_EXPORT __attribute__((visibility("default"))) +# define UHD_IMPORT __attribute__((visibility("default"))) +# define UHD_INLINE inline __attribute__((always_inline)) +# define UHD_FORCE_INLINE inline __attribute__((always_inline)) +# define UHD_DEPRECATED __attribute__((deprecated)) +# define UHD_ALIGNED(x) __attribute__((aligned(x))) +# define UHD_UNUSED(x) x __attribute__((unused)) #elif defined(__clang__) - #define UHD_EXPORT __attribute__((visibility("default"))) - #define UHD_IMPORT __attribute__((visibility("default"))) - #define UHD_INLINE inline __attribute__((always_inline)) - #define UHD_FORCE_INLINE inline __attribute__((always_inline)) - #define UHD_DEPRECATED __attribute__((deprecated)) - #define UHD_ALIGNED(x) __attribute__((aligned(x))) - #define UHD_UNUSED(x) x __attribute__((unused)) +# define UHD_EXPORT __attribute__((visibility("default"))) +# define UHD_IMPORT __attribute__((visibility("default"))) +# define UHD_INLINE inline __attribute__((always_inline)) +# define UHD_FORCE_INLINE inline __attribute__((always_inline)) +# define UHD_DEPRECATED __attribute__((deprecated)) +# define UHD_ALIGNED(x) __attribute__((aligned(x))) +# define UHD_UNUSED(x) x __attribute__((unused)) #else - #define UHD_EXPORT - #define UHD_IMPORT - #define UHD_INLINE inline - #define UHD_FORCE_INLINE inline - #define UHD_DEPRECATED - #define UHD_ALIGNED(x) - #define UHD_UNUSED(x) x +# define UHD_EXPORT +# define UHD_IMPORT +# define UHD_INLINE inline +# define UHD_FORCE_INLINE inline +# define UHD_DEPRECATED +# define UHD_ALIGNED(x) +# define UHD_UNUSED(x) x #endif // Define API declaration macro #ifdef UHD_STATIC_LIB - #define UHD_API +# define UHD_API #else - #ifdef UHD_DLL_EXPORTS - #define UHD_API UHD_EXPORT - #else - #define UHD_API UHD_IMPORT - #endif // UHD_DLL_EXPORTS +# ifdef UHD_DLL_EXPORTS +# define UHD_API UHD_EXPORT +# else +# define UHD_API UHD_IMPORT +# endif // UHD_DLL_EXPORTS #endif // UHD_STATIC_LIB #ifdef UHD_RFNOC_ENABLED - #define UHD_RFNOC_API UHD_API +# define UHD_RFNOC_API UHD_API #else - #define UHD_RFNOC_API +# define UHD_RFNOC_API #endif // UHD_RFNOC_ENABLED // Platform defines for conditional parts of headers: // Taken from boost/config/select_platform_config.hpp, // however, we define macros, not strings for platforms. -#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GLIBC__)) && !defined(_CRAYC) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) - #define UHD_PLATFORM_LINUX +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GLIBC__)) \ + && !defined(_CRAYC) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) +# define UHD_PLATFORM_LINUX #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) - #define UHD_PLATFORM_WIN32 +# define UHD_PLATFORM_WIN32 #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) - #define UHD_PLATFORM_MACOS -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__) - #define UHD_PLATFORM_BSD +# define UHD_PLATFORM_MACOS +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(__FreeBSD_kernel__) +# define UHD_PLATFORM_BSD #endif // Define 'stringize' preprocessor macros. The stringize macro, XSTR, takes @@ -118,9 +125,9 @@ typedef ptrdiff_t ssize_t; // There are two different versions because MSVC handles this syntax a bit // differently than other compilers. #if defined(BOOST_MSVC) - #define XSTR(x,...) #x +# define XSTR(x, ...) # x #else - #define XSTR(x...) #x +# define XSTR(x...) # x #endif #define STR(x) XSTR(x) diff --git a/host/include/uhd/convert.hpp b/host/include/uhd/convert.hpp index 64cebe945..3af7cc47b 100644 --- a/host/include/uhd/convert.hpp +++ b/host/include/uhd/convert.hpp @@ -10,99 +10,96 @@ #include <uhd/config.hpp> #include <uhd/types/ref_vector.hpp> -#include <boost/shared_ptr.hpp> #include <boost/function.hpp> #include <boost/operators.hpp> +#include <boost/shared_ptr.hpp> #include <string> -namespace uhd{ namespace convert{ - - //! A conversion class that implements a conversion from inputs -> outputs. - class converter{ - public: - typedef boost::shared_ptr<converter> sptr; - typedef uhd::ref_vector<void *> output_type; - typedef uhd::ref_vector<const void *> input_type; - - virtual ~converter(void) = 0; - - //! Set the scale factor (used in floating point conversions) - virtual void set_scalar(const double) = 0; - - //! The public conversion method to convert inputs -> outputs - UHD_INLINE void conv(const input_type &in, const output_type &out, const size_t num){ - if (num != 0) (*this)(in, out, num); - } - - private: - //! Callable method: input vectors, output vectors, num samples - // - // This is the guts of the converter. When deriving new converter types, - // this is where the actual conversion routines go. - // - // \param in Pointers to the input buffers - // \param out Pointers to the output buffers - // \param num Number of items in the input buffers to convert - virtual void operator()(const input_type& in, const output_type& out, const size_t num) = 0; - }; - - //! Conversion factory function typedef - typedef boost::function<converter::sptr(void)> function_type; - - //! Priority of conversion routines - typedef int priority_type; - - //! Identify a conversion routine in the registry - struct UHD_API id_type : boost::equality_comparable<id_type>{ - std::string input_format; - size_t num_inputs; - std::string output_format; - size_t num_outputs; - std::string to_pp_string(void) const; - std::string to_string(void) const; - }; - - //! Implement equality_comparable interface - UHD_API bool operator==(const id_type &, const id_type &); - - /*! - * Register a converter function. - * - * Converters with higher priority are given preference. - * - * \param id identify the conversion - * \param fcn makes a new converter - * \param prio the function priority - */ - UHD_API void register_converter( - const id_type &id, - const function_type &fcn, - const priority_type prio - ); - - /*! - * Get a converter factory function. - * \param id identify the conversion - * \param prio the desired prio or -1 for best - * \return the converter factory function - */ - UHD_API function_type get_converter( - const id_type &id, - const priority_type prio = -1 - ); - - /*! - * Register the size of a particular item. - * \param format the item format - * \param size the size in bytes - */ - UHD_API void register_bytes_per_item( - const std::string &format, const size_t size - ); - - //! Convert an item format to a size in bytes - UHD_API size_t get_bytes_per_item(const std::string &format); - -}} //namespace +namespace uhd { namespace convert { + +//! A conversion class that implements a conversion from inputs -> outputs. +class converter +{ +public: + typedef boost::shared_ptr<converter> sptr; + typedef uhd::ref_vector<void*> output_type; + typedef uhd::ref_vector<const void*> input_type; + + virtual ~converter(void) = 0; + + //! Set the scale factor (used in floating point conversions) + virtual void set_scalar(const double) = 0; + + //! The public conversion method to convert inputs -> outputs + UHD_INLINE void conv(const input_type& in, const output_type& out, const size_t num) + { + if (num != 0) + (*this)(in, out, num); + } + +private: + //! Callable method: input vectors, output vectors, num samples + // + // This is the guts of the converter. When deriving new converter types, + // this is where the actual conversion routines go. + // + // \param in Pointers to the input buffers + // \param out Pointers to the output buffers + // \param num Number of items in the input buffers to convert + virtual void operator()( + const input_type& in, const output_type& out, const size_t num) = 0; +}; + +//! Conversion factory function typedef +typedef boost::function<converter::sptr(void)> function_type; + +//! Priority of conversion routines +typedef int priority_type; + +//! Identify a conversion routine in the registry +struct UHD_API id_type : boost::equality_comparable<id_type> +{ + std::string input_format; + size_t num_inputs; + std::string output_format; + size_t num_outputs; + std::string to_pp_string(void) const; + std::string to_string(void) const; +}; + +//! Implement equality_comparable interface +UHD_API bool operator==(const id_type&, const id_type&); + +/*! + * Register a converter function. + * + * Converters with higher priority are given preference. + * + * \param id identify the conversion + * \param fcn makes a new converter + * \param prio the function priority + */ +UHD_API void register_converter( + const id_type& id, const function_type& fcn, const priority_type prio); + +/*! + * Get a converter factory function. + * \param id identify the conversion + * \param prio the desired prio or -1 for best + * \return the converter factory function + */ +UHD_API function_type get_converter(const id_type& id, const priority_type prio = -1); + +/*! + * Register the size of a particular item. + * \param format the item format + * \param size the size in bytes + */ +UHD_API void register_bytes_per_item(const std::string& format, const size_t size); + +//! Convert an item format to a size in bytes +UHD_API size_t get_bytes_per_item(const std::string& format); + +}} // namespace uhd::convert #endif /* INCLUDED_UHD_CONVERT_HPP */ diff --git a/host/include/uhd/deprecated.hpp b/host/include/uhd/deprecated.hpp index 91635f8ca..0eeefecee 100644 --- a/host/include/uhd/deprecated.hpp +++ b/host/include/uhd/deprecated.hpp @@ -10,58 +10,58 @@ // #ifndef INCLUDED_UHD_TYPES_OTW_TYPE_HPP -#define INCLUDED_UHD_TYPES_OTW_TYPE_HPP +# define INCLUDED_UHD_TYPES_OTW_TYPE_HPP -#include <uhd/config.hpp> -#include <cstddef> +# include <uhd/config.hpp> +# include <cstddef> -namespace uhd{ +namespace uhd { +/*! + * Description for over-the-wire integers: + * The DSP units in the FPGA deal with signed 16-bit integers. + * The width and shift define the translation between OTW and DSP, + * defined by the following relation: otw_int = dsp_int >> shift + * + * Note: possible combinations of width, shift, and byteorder + * depend on the internals of the FPGA. Not all are supported! + */ +struct UHD_API otw_type_t +{ /*! - * Description for over-the-wire integers: - * The DSP units in the FPGA deal with signed 16-bit integers. - * The width and shift define the translation between OTW and DSP, - * defined by the following relation: otw_int = dsp_int >> shift - * - * Note: possible combinations of width, shift, and byteorder - * depend on the internals of the FPGA. Not all are supported! + * Width of an over-the-wire integer in bits. */ - struct UHD_API otw_type_t{ + size_t width; // in bits - /*! - * Width of an over-the-wire integer in bits. - */ - size_t width; //in bits - - /*! - * Shift of an over-the-wire integer in bits. - * otw_int = dsp_int >> shift - * dsp_int = otw_int << shift - */ - size_t shift; //in bits + /*! + * Shift of an over-the-wire integer in bits. + * otw_int = dsp_int >> shift + * dsp_int = otw_int << shift + */ + size_t shift; // in bits - /*! - * Constants for byte order (borrowed from numpy's dtype) - */ - enum /*bo_t*/ { - BO_NATIVE = int('='), - BO_LITTLE_ENDIAN = int('<'), - BO_BIG_ENDIAN = int('>'), - BO_NOT_APPLICABLE = int('|') - } byteorder; + /*! + * Constants for byte order (borrowed from numpy's dtype) + */ + enum /*bo_t*/ { + BO_NATIVE = int('='), + BO_LITTLE_ENDIAN = int('<'), + BO_BIG_ENDIAN = int('>'), + BO_NOT_APPLICABLE = int('|') + } byteorder; - /*! - * Get the sample size of this otw type. - * \return the size of a sample in bytes - */ - size_t get_sample_size(void) const; + /*! + * Get the sample size of this otw type. + * \return the size of a sample in bytes + */ + size_t get_sample_size(void) const; - otw_type_t(void); - }; + otw_type_t(void); +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_OTW_TYPE_HPP */ -#include <uhd/types/io_type.hpp> //wish it was in here #include <uhd/types/clock_config.hpp> //wish it was in here +#include <uhd/types/io_type.hpp> //wish it was in here diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index e0f8e3b60..9aecdc088 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -9,35 +9,31 @@ #define INCLUDED_UHD_DEVICE_HPP #include <uhd/config.hpp> -#include <uhd/stream.hpp> #include <uhd/deprecated.hpp> #include <uhd/property_tree.hpp> +#include <uhd/stream.hpp> #include <uhd/types/device_addr.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> #include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> -namespace uhd{ +namespace uhd { -class property_tree; //forward declaration +class property_tree; // forward declaration /*! * The device interface represents the hardware. * The API allows for discovery, configuration, and streaming. */ -class UHD_API device : boost::noncopyable{ - +class UHD_API device : boost::noncopyable +{ public: typedef boost::shared_ptr<device> sptr; - typedef boost::function<device_addrs_t(const device_addr_t &)> find_t; - typedef boost::function<sptr(const device_addr_t &)> make_t; + typedef boost::function<device_addrs_t(const device_addr_t&)> find_t; + typedef boost::function<sptr(const device_addr_t&)> make_t; //! Device type, used as a filter in make - enum device_filter_t { - ANY, - USRP, - CLOCK - }; + enum device_filter_t { ANY, USRP, CLOCK }; virtual ~device(void) = 0; /*! @@ -48,10 +44,7 @@ public: * \param filter include only USRP devices, clock devices, or both */ static void register_device( - const find_t &find, - const make_t &make, - const device_filter_t filter - ); + const find_t& find, const make_t& make, const device_filter_t filter); /*! * \brief Find devices attached to the host. @@ -63,7 +56,7 @@ public: * \param filter an optional filter to exclude USRP or clock devices * \return a vector of device addresses for all devices on the system */ - static device_addrs_t find(const device_addr_t &hint, device_filter_t filter = ANY); + static device_addrs_t find(const device_addr_t& hint, device_filter_t filter = ANY); /*! * \brief Create a new device from the device address hint. @@ -79,21 +72,22 @@ public: * \param which which address to use when multiple are found * \return a shared pointer to a new device instance */ - static sptr make(const device_addr_t &hint, device_filter_t filter = ANY, size_t which = 0); + static sptr make( + const device_addr_t& hint, device_filter_t filter = ANY, size_t which = 0); /*! \brief Make a new receive streamer from the streamer arguments * * Note: There can always only be one streamer. When calling get_rx_stream() * a second time, the first streamer must be destroyed beforehand. */ - virtual rx_streamer::sptr get_rx_stream(const stream_args_t &args) = 0; + virtual rx_streamer::sptr get_rx_stream(const stream_args_t& args) = 0; /*! \brief Make a new transmit streamer from the streamer arguments * * Note: There can always only be one streamer. When calling get_tx_stream() * a second time, the first streamer must be destroyed beforehand. */ - virtual tx_streamer::sptr get_tx_stream(const stream_args_t &args) = 0; + virtual tx_streamer::sptr get_tx_stream(const stream_args_t& args) = 0; /*! * Receive and asynchronous message from the device. @@ -102,8 +96,7 @@ public: * \return true when the async_metadata is valid, false for timeout */ virtual bool recv_async_msg( - async_metadata_t &async_metadata, double timeout = 0.1 - ) = 0; + async_metadata_t& async_metadata, double timeout = 0.1) = 0; //! Get access to the underlying property structure uhd::property_tree::sptr get_tree(void) const; @@ -116,6 +109,6 @@ protected: device_filter_t _type; }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_DEVICE_HPP */ diff --git a/host/include/uhd/device3.hpp b/host/include/uhd/device3.hpp index af304d37d..8dca2bc47 100644 --- a/host/include/uhd/device3.hpp +++ b/host/include/uhd/device3.hpp @@ -9,10 +9,10 @@ #define INCLUDED_UHD_DEVICE3_HPP #include <uhd/device.hpp> -#include <uhd/rfnoc/graph.hpp> #include <uhd/rfnoc/block_ctrl_base.hpp> -#include <boost/units/detail/utility.hpp> +#include <uhd/rfnoc/graph.hpp> #include <boost/thread/mutex.hpp> +#include <boost/units/detail/utility.hpp> #include <vector> namespace uhd { @@ -24,15 +24,15 @@ namespace uhd { * - They support RFNoC (RF Network-on-Chip). * - Data transport uses the compressed VITA (CVITA/CHDR) data format. */ -class UHD_API device3 : public uhd::device { - - public: +class UHD_API device3 : public uhd::device +{ +public: typedef boost::shared_ptr<device3> sptr; //! Same as uhd::device::make(), but will fail if not actually a device3 - static sptr make(const device_addr_t &hint, const size_t which = 0); + static sptr make(const device_addr_t& hint, const size_t which = 0); - virtual rfnoc::graph::sptr create_graph(const std::string &name="") = 0; + virtual rfnoc::graph::sptr create_graph(const std::string& name = "") = 0; /*! Reset blocks after a stream. * @@ -46,15 +46,14 @@ class UHD_API device3 : public uhd::device { * \return true if a block with the specified id exists * \note this access is not thread safe if peformed during block enumeration */ - bool has_block(const rfnoc::block_id_t &block_id) const; + bool has_block(const rfnoc::block_id_t& block_id) const; /*! Same as has_block(), but with a type check. * * \return true if a block of type T with the specified id exists * \note this access is not thread safe if peformed during block enumeration */ - template <typename T> - bool has_block(const rfnoc::block_id_t &block_id) const + template <typename T> bool has_block(const rfnoc::block_id_t& block_id) const { if (has_block(block_id)) { return bool(boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id))); @@ -71,7 +70,7 @@ class UHD_API device3 : public uhd::device { * \param block_id Canonical block name (e.g. "0/FFT_1"). * \note this access is not thread safe if peformed during block enumeration */ - rfnoc::block_ctrl_base::sptr get_block_ctrl(const rfnoc::block_id_t &block_id) const; + rfnoc::block_ctrl_base::sptr get_block_ctrl(const rfnoc::block_id_t& block_id) const; /*! Same as get_block_ctrl(), but with a type cast. * @@ -82,19 +81,22 @@ class UHD_API device3 : public uhd::device { * * \code{.cpp} * // Assume DEV is a device3::sptr - * uhd::rfnoc::my_block_ctrl::sptr block_controller = get_block_ctrl<my_block_ctrl>("0/MyBlock_0"); + * uhd::rfnoc::my_block_ctrl::sptr block_controller = + * get_block_ctrl<my_block_ctrl>("0/MyBlock_0"); * block_controller->my_own_block_method(); * \endcode * \note this access is not thread safe if peformed during block enumeration */ template <typename T> - boost::shared_ptr<T> get_block_ctrl(const rfnoc::block_id_t &block_id) const + boost::shared_ptr<T> get_block_ctrl(const rfnoc::block_id_t& block_id) const { - boost::shared_ptr<T> blk = boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id)); + boost::shared_ptr<T> blk = + boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id)); if (blk) { return blk; } else { - throw uhd::lookup_error(str(boost::format("This device does not have a block of type %s with ID: %s") + throw uhd::lookup_error(str( + boost::format("This device does not have a block of type %s with ID: %s") % boost::units::detail::demangle(typeid(T).name()) % block_id.to_string())); } @@ -108,16 +110,16 @@ class UHD_API device3 : public uhd::device { * use the templated version of this function, e.g. * \code{.cpp} * // Assume DEV is a device3::sptr - * null_block_ctrl::sptr null_block = DEV->find_blocks<null_block_ctrl>("NullSrcSink"); - * \endcode - * \note this access is not thread safe if peformed during block enumeration + * null_block_ctrl::sptr null_block = + * DEV->find_blocks<null_block_ctrl>("NullSrcSink"); \endcode \note this access is not + * thread safe if peformed during block enumeration */ - std::vector<rfnoc::block_id_t> find_blocks(const std::string &block_id_hint) const; + std::vector<rfnoc::block_id_t> find_blocks(const std::string& block_id_hint) const; /*! Type-cast version of find_blocks(). */ template <typename T> - std::vector<rfnoc::block_id_t> find_blocks(const std::string &block_id_hint) const + std::vector<rfnoc::block_id_t> find_blocks(const std::string& block_id_hint) const { std::vector<rfnoc::block_id_t> all_block_ids = find_blocks(block_id_hint); std::vector<rfnoc::block_id_t> filt_block_ids; @@ -129,15 +131,15 @@ class UHD_API device3 : public uhd::device { return filt_block_ids; } - protected: +protected: //! List of *all* RFNoC blocks available on this device. // It is the responsibility of the deriving class to make // sure this gets correctly populated. - std::vector< rfnoc::block_ctrl_base::sptr > _rfnoc_block_ctrl; + std::vector<rfnoc::block_ctrl_base::sptr> _rfnoc_block_ctrl; //! Mutex to protect access to members - boost::mutex _block_ctrl_mutex; + boost::mutex _block_ctrl_mutex; }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_DEVICE3_HPP */ diff --git a/host/include/uhd/exception.hpp b/host/include/uhd/exception.hpp index 727c09697..7189015a0 100644 --- a/host/include/uhd/exception.hpp +++ b/host/include/uhd/exception.hpp @@ -30,200 +30,220 @@ * * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2106.html */ -namespace uhd{ - - /*! Base class of all UHD-specific exceptions. - */ - struct UHD_API exception : std::runtime_error{ - exception(const std::string &what); - virtual unsigned code(void) const = 0; - virtual exception *dynamic_clone(void) const = 0; - virtual void dynamic_throw(void) const = 0; - }; - - /*! Raised when an assert statement fails. - * - * This includes our own assertion macros, such as UHD_ASSERT_THROW(). - */ - struct UHD_API assertion_error : exception{ - assertion_error(const std::string &what); - virtual unsigned code(void) const; - virtual assertion_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! The base class for exceptions that are raised when a key or index is - * invalid. - */ - struct UHD_API lookup_error : exception{ - lookup_error(const std::string &what); - virtual unsigned code(void) const; - virtual lookup_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when a sequence index is out of range. - */ - struct UHD_API index_error : lookup_error{ - index_error(const std::string &what); - virtual unsigned code(void) const; - virtual index_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when a dictionary-like object is trying to be indexed by an - * invalid key. - * - * This includes the property tree. - */ - struct UHD_API key_error : lookup_error{ - key_error(const std::string &what); - virtual unsigned code(void) const; - virtual key_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when an operation or function is executed with a value of - * incorrect type. - * - * This might occur when values are being passed around as strings, but the - * underlying code will need convert to a native type. - */ - struct UHD_API type_error : exception{ - type_error(const std::string &what); - virtual unsigned code(void) const; - virtual type_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when an operation or function receives an argument that has the - * right type but an inappropriate or invalid value, and no other exception - * is more specific. - */ - struct UHD_API value_error : exception{ - value_error(const std::string &what); - virtual unsigned code(void) const; - virtual value_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when a value is inappropriate because it can't be narrowed as - * required. - * - * Mostly raised by uhd::narrow() - */ - struct UHD_API narrowing_error : value_error{ - narrowing_error(const std::string &what); - virtual unsigned code(void) const; - virtual narrowing_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when an error is detected that doesn't fall into any of the - * categories. - */ - struct UHD_API runtime_error : exception{ - runtime_error(const std::string &what); - virtual unsigned code(void) const; - virtual runtime_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when an error occurs during a USB transaction. - */ - struct UHD_API usb_error : runtime_error{ - int _code; - usb_error(int code, const std::string &what); - virtual unsigned code(void) const { return _code; }; - virtual usb_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when a function is stubbed out but doesn't actually do anything - * useful. - */ - struct UHD_API not_implemented_error : runtime_error{ - not_implemented_error(const std::string &what); - virtual unsigned code(void) const; - virtual not_implemented_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; +namespace uhd { - /*! Base class for errors that occur outside of UHD. - */ - struct UHD_API environment_error : exception{ - environment_error(const std::string &what); - virtual unsigned code(void) const; - virtual environment_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when an I/O operation fails for an I/O-related reason. - */ - struct UHD_API io_error : environment_error{ - io_error(const std::string &what); - virtual unsigned code(void) const; - virtual io_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; - - /*! Raised when a function returns a system-related error. - */ - struct UHD_API os_error : environment_error{ - os_error(const std::string &what); - virtual unsigned code(void) const; - virtual os_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; +/*! Base class of all UHD-specific exceptions. + */ +struct UHD_API exception : std::runtime_error +{ + exception(const std::string& what); + virtual unsigned code(void) const = 0; + virtual exception* dynamic_clone(void) const = 0; + virtual void dynamic_throw(void) const = 0; +}; + +/*! Raised when an assert statement fails. + * + * This includes our own assertion macros, such as UHD_ASSERT_THROW(). + */ +struct UHD_API assertion_error : exception +{ + assertion_error(const std::string& what); + virtual unsigned code(void) const; + virtual assertion_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! The base class for exceptions that are raised when a key or index is + * invalid. + */ +struct UHD_API lookup_error : exception +{ + lookup_error(const std::string& what); + virtual unsigned code(void) const; + virtual lookup_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when a sequence index is out of range. + */ +struct UHD_API index_error : lookup_error +{ + index_error(const std::string& what); + virtual unsigned code(void) const; + virtual index_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when a dictionary-like object is trying to be indexed by an + * invalid key. + * + * This includes the property tree. + */ +struct UHD_API key_error : lookup_error +{ + key_error(const std::string& what); + virtual unsigned code(void) const; + virtual key_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when an operation or function is executed with a value of + * incorrect type. + * + * This might occur when values are being passed around as strings, but the + * underlying code will need convert to a native type. + */ +struct UHD_API type_error : exception +{ + type_error(const std::string& what); + virtual unsigned code(void) const; + virtual type_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when an operation or function receives an argument that has the + * right type but an inappropriate or invalid value, and no other exception + * is more specific. + */ +struct UHD_API value_error : exception +{ + value_error(const std::string& what); + virtual unsigned code(void) const; + virtual value_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when a value is inappropriate because it can't be narrowed as + * required. + * + * Mostly raised by uhd::narrow() + */ +struct UHD_API narrowing_error : value_error +{ + narrowing_error(const std::string& what); + virtual unsigned code(void) const; + virtual narrowing_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when an error is detected that doesn't fall into any of the + * categories. + */ +struct UHD_API runtime_error : exception +{ + runtime_error(const std::string& what); + virtual unsigned code(void) const; + virtual runtime_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when an error occurs during a USB transaction. + */ +struct UHD_API usb_error : runtime_error +{ + int _code; + usb_error(int code, const std::string& what); + virtual unsigned code(void) const + { + return _code; + }; + virtual usb_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when a function is stubbed out but doesn't actually do anything + * useful. + */ +struct UHD_API not_implemented_error : runtime_error +{ + not_implemented_error(const std::string& what); + virtual unsigned code(void) const; + virtual not_implemented_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Base class for errors that occur outside of UHD. + */ +struct UHD_API environment_error : exception +{ + environment_error(const std::string& what); + virtual unsigned code(void) const; + virtual environment_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when an I/O operation fails for an I/O-related reason. + */ +struct UHD_API io_error : environment_error +{ + io_error(const std::string& what); + virtual unsigned code(void) const; + virtual io_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when a function returns a system-related error. + */ +struct UHD_API os_error : environment_error +{ + os_error(const std::string& what); + virtual unsigned code(void) const; + virtual os_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! \deprecated + */ +struct UHD_API system_error : exception +{ + system_error(const std::string& what); + virtual unsigned code(void) const; + virtual system_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; + +/*! Raised when a parser encounters a syntax error. + * + * Within UHD, this is limited to Noc-Script execution. + */ +struct UHD_API syntax_error : exception +{ + syntax_error(const std::string& what); + virtual unsigned code(void) const; + virtual syntax_error* dynamic_clone(void) const; + virtual void dynamic_throw(void) const; +}; - /*! \deprecated - */ - struct UHD_API system_error : exception{ - system_error(const std::string &what); - virtual unsigned code(void) const; - virtual system_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; +/*! + * Create a formatted string with throw-site information. + * Fills in the function name, file name, and line number. + * \param what the std::exception message + * \return the formatted exception message + */ +#define UHD_THROW_SITE_INFO(what) \ + std::string(std::string(what) + "\n" + " in " + std::string(BOOST_CURRENT_FUNCTION) \ + + "\n" + " at " + std::string(__FILE__) + ":" \ + + BOOST_STRINGIZE(__LINE__) + "\n") - /*! Raised when a parser encounters a syntax error. - * - * Within UHD, this is limited to Noc-Script execution. - */ - struct UHD_API syntax_error : exception{ - syntax_error(const std::string &what); - virtual unsigned code(void) const; - virtual syntax_error *dynamic_clone(void) const; - virtual void dynamic_throw(void) const; - }; +/*! + * Throws an invalid code path exception with throw-site information. + * Use this macro in places that code execution is not supposed to go. + */ +#define UHD_THROW_INVALID_CODE_PATH() \ + throw uhd::system_error(UHD_THROW_SITE_INFO("invalid code path")) - /*! - * Create a formatted string with throw-site information. - * Fills in the function name, file name, and line number. - * \param what the std::exception message - * \return the formatted exception message - */ - #define UHD_THROW_SITE_INFO(what) std::string( \ - std::string(what) + "\n" + \ - " in " + std::string(BOOST_CURRENT_FUNCTION) + "\n" + \ - " at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \ - ) - - /*! - * Throws an invalid code path exception with throw-site information. - * Use this macro in places that code execution is not supposed to go. - */ - #define UHD_THROW_INVALID_CODE_PATH() \ - throw uhd::system_error(UHD_THROW_SITE_INFO("invalid code path")) - - /*! - * Assert the result of the code evaluation. - * If the code evaluates to false, throw an assertion error. - * \param code the code that resolved to a boolean - */ - #define UHD_ASSERT_THROW(code) {if (not (code)) \ - throw uhd::assertion_error(UHD_THROW_SITE_INFO(#code)); \ +/*! + * Assert the result of the code evaluation. + * If the code evaluates to false, throw an assertion error. + * \param code the code that resolved to a boolean + */ +#define UHD_ASSERT_THROW(code) \ + { \ + if (not(code)) \ + throw uhd::assertion_error(UHD_THROW_SITE_INFO(#code)); \ } -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_EXCEPTION_HPP */ diff --git a/host/include/uhd/image_loader.hpp b/host/include/uhd/image_loader.hpp index 6556bbdd8..3b4b9133e 100644 --- a/host/include/uhd/image_loader.hpp +++ b/host/include/uhd/image_loader.hpp @@ -8,21 +8,19 @@ #ifndef INCLUDED_UHD_IMAGE_LOADER_HPP #define INCLUDED_UHD_IMAGE_LOADER_HPP -#include <string> - -#include <boost/function.hpp> -#include <boost/noncopyable.hpp> - #include <uhd/config.hpp> #include <uhd/types/device_addr.hpp> +#include <boost/function.hpp> +#include <boost/noncopyable.hpp> +#include <string> -namespace uhd{ - -class UHD_API image_loader : boost::noncopyable{ +namespace uhd { +class UHD_API image_loader : boost::noncopyable +{ public: - - typedef struct{ + typedef struct + { uhd::device_addr_t args; bool load_firmware; bool load_fpga; @@ -48,7 +46,7 @@ public: * device and expect the default image(s) to be loaded, but the specific * model of the device cannot be determined beyond a category. */ - typedef boost::function<bool(const image_loader_args_t &)> loader_fcn_t; + typedef boost::function<bool(const image_loader_args_t&)> loader_fcn_t; //! Register an image loader /*! @@ -56,17 +54,15 @@ public: * \param loader_fcn the loader function for the given device * \param recovery_instructions instructions on how to restore a device */ - static void register_image_loader( - const std::string &device_type, - const loader_fcn_t &loader_fcn, - const std::string &recovery_instructions - ); + static void register_image_loader(const std::string& device_type, + const loader_fcn_t& loader_fcn, + const std::string& recovery_instructions); //! Load firmware and/or FPGA onto a device /*! * \param image_loader_args arguments to pass into image loading function */ - static bool load(const image_loader_args_t &image_loader_args); + static bool load(const image_loader_args_t& image_loader_args); //! Get the instructions on how to recovery a particular device /*! @@ -75,9 +71,9 @@ public: * \param device_type the "type=foo" value given in an --args option * \return recovery instructions */ - static std::string get_recovery_instructions(const std::string &device_type); + static std::string get_recovery_instructions(const std::string& device_type); }; -} +} // namespace uhd #endif /* INCLUDED_UHD_IMAGE_LOADER_HPP */ diff --git a/host/include/uhd/property_tree.hpp b/host/include/uhd/property_tree.hpp index 84466e62a..173398986 100644 --- a/host/include/uhd/property_tree.hpp +++ b/host/include/uhd/property_tree.hpp @@ -9,12 +9,12 @@ #define INCLUDED_UHD_PROPERTY_TREE_HPP #include <uhd/config.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> #include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> #include <vector> -namespace uhd{ +namespace uhd { /*! * A templated property interface for holding the state @@ -63,11 +63,12 @@ namespace uhd{ * - T must have a copy constructor * - T must have an assignment operator */ -template <typename T> class property : boost::noncopyable{ +template <typename T> class property : boost::noncopyable +{ public: - typedef boost::function<void(const T &)> subscriber_type; + typedef boost::function<void(const T&)> subscriber_type; typedef boost::function<T(void)> publisher_type; - typedef boost::function<T(const T &)> coercer_type; + typedef boost::function<T(const T&)> coercer_type; virtual ~property<T>(void) = 0; @@ -81,7 +82,7 @@ public: * \return a reference to this property for chaining * \throws uhd::assertion_error if called more than once */ - virtual property<T> &set_coercer(const coercer_type &coercer) = 0; + virtual property<T>& set_coercer(const coercer_type& coercer) = 0; /*! * Register a publisher into the property. @@ -93,7 +94,7 @@ public: * \return a reference to this property for chaining * \throws uhd::assertion_error if called more than once */ - virtual property<T> &set_publisher(const publisher_type &publisher) = 0; + virtual property<T>& set_publisher(const publisher_type& publisher) = 0; /*! * Register a subscriber into the property. @@ -104,7 +105,7 @@ public: * \param subscriber the subscriber callback function * \return a reference to this property for chaining */ - virtual property<T> &add_desired_subscriber(const subscriber_type &subscriber) = 0; + virtual property<T>& add_desired_subscriber(const subscriber_type& subscriber) = 0; /*! * Register a subscriber into the property. @@ -115,7 +116,7 @@ public: * \param subscriber the subscriber callback function * \return a reference to this property for chaining */ - virtual property<T> &add_coerced_subscriber(const subscriber_type &subscriber) = 0; + virtual property<T>& add_coerced_subscriber(const subscriber_type& subscriber) = 0; /*! * Update calls all subscribers w/ the current value. @@ -123,7 +124,7 @@ public: * \return a reference to this property for chaining * \throws uhd::assertion_error */ - virtual property<T> &update(void) = 0; + virtual property<T>& update(void) = 0; /*! * Set the new value and call all the necessary subscribers. @@ -137,7 +138,7 @@ public: * \return a reference to this property for chaining * \throws uhd::assertion_error */ - virtual property<T> &set(const T &value) = 0; + virtual property<T>& set(const T& value) = 0; /*! * Set a coerced value and call all subscribers. @@ -150,7 +151,7 @@ public: * \return a reference to this property for chaining * \throws uhd::assertion_error */ - virtual property<T> &set_coerced(const T &value) = 0; + virtual property<T>& set_coerced(const T& value) = 0; /*! * Get the current value of this property. @@ -179,8 +180,8 @@ public: virtual bool empty(void) const = 0; }; -template <typename T> -property<T>::~property(void){ +template <typename T> property<T>::~property(void) +{ /* NOP */ } @@ -191,21 +192,23 @@ property<T>::~property(void){ * Notice: we do not declare UHD_API on the whole structure * because MSVC will do weird things with std::string and linking. */ -struct fs_path : std::string{ +struct fs_path : std::string +{ UHD_API fs_path(void); - UHD_API fs_path(const char *); - UHD_API fs_path(const std::string &); + UHD_API fs_path(const char*); + UHD_API fs_path(const std::string&); UHD_API std::string leaf(void) const; UHD_API fs_path branch_path(void) const; }; -UHD_API fs_path operator/(const fs_path &, const fs_path &); -UHD_API fs_path operator/(const fs_path &, size_t); +UHD_API fs_path operator/(const fs_path&, const fs_path&); +UHD_API fs_path operator/(const fs_path&, size_t); /*! * The property tree provides a file system structure for accessing properties. */ -class UHD_API property_tree : boost::noncopyable{ +class UHD_API property_tree : boost::noncopyable +{ public: typedef boost::shared_ptr<property_tree> sptr; @@ -217,35 +220,33 @@ public: static sptr make(void); //! Get a subtree with a new root starting at path - virtual sptr subtree(const fs_path &path) const = 0; + virtual sptr subtree(const fs_path& path) const = 0; //! Remove a property or directory (recursive) - virtual void remove(const fs_path &path) = 0; + virtual void remove(const fs_path& path) = 0; //! True if the path exists in the tree - virtual bool exists(const fs_path &path) const = 0; + virtual bool exists(const fs_path& path) const = 0; //! Get an iterable to all things in the given path - virtual std::vector<std::string> list(const fs_path &path) const = 0; + virtual std::vector<std::string> list(const fs_path& path) const = 0; //! Create a new property entry in the tree - template <typename T> property<T> &create( - const fs_path &path, - coerce_mode_t coerce_mode = AUTO_COERCE); + template <typename T> + property<T>& create(const fs_path& path, coerce_mode_t coerce_mode = AUTO_COERCE); //! Get access to a property in the tree - template <typename T> property<T> &access(const fs_path &path); + template <typename T> property<T>& access(const fs_path& path); private: //! Internal create property with wild-card type - virtual void _create(const fs_path &path, const boost::shared_ptr<void> &prop) = 0; + virtual void _create(const fs_path& path, const boost::shared_ptr<void>& prop) = 0; //! Internal access property with wild-card type - virtual boost::shared_ptr<void> &_access(const fs_path &path) const = 0; - + virtual boost::shared_ptr<void>& _access(const fs_path& path) const = 0; }; -} //namespace uhd +} // namespace uhd #include <uhd/property_tree.ipp> diff --git a/host/include/uhd/rfnoc/block_ctrl.hpp b/host/include/uhd/rfnoc/block_ctrl.hpp index 9a8c5f8ec..c26ee0f85 100644 --- a/host/include/uhd/rfnoc/block_ctrl.hpp +++ b/host/include/uhd/rfnoc/block_ctrl.hpp @@ -8,11 +8,10 @@ #ifndef INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief This is the default implementation of a block_ctrl_base. * @@ -20,7 +19,8 @@ namespace uhd { * can be set by sr_write(). The default behaviour of functions is documented * in uhd::rfnoc::block_ctrl_base. */ -class UHD_RFNOC_API block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base +class UHD_RFNOC_API block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base { public: // Required macro in RFNoC block classes diff --git a/host/include/uhd/rfnoc/block_ctrl_base.hpp b/host/include/uhd/rfnoc/block_ctrl_base.hpp index 4b97fa185..0bf701810 100644 --- a/host/include/uhd/rfnoc/block_ctrl_base.hpp +++ b/host/include/uhd/rfnoc/block_ctrl_base.hpp @@ -9,36 +9,34 @@ #define INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP #include <uhd/property_tree.hpp> +#include <uhd/rfnoc/block_id.hpp> +#include <uhd/rfnoc/blockdef.hpp> +#include <uhd/rfnoc/constants.hpp> +#include <uhd/rfnoc/node_ctrl_base.hpp> +#include <uhd/rfnoc/stream_sig.hpp> #include <uhd/stream.hpp> #include <uhd/types/sid.hpp> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/wb_iface.hpp> #include <uhd/utils/static.hpp> -#include <uhd/rfnoc/node_ctrl_base.hpp> -#include <uhd/rfnoc/block_id.hpp> -#include <uhd/rfnoc/stream_sig.hpp> -#include <uhd/rfnoc/blockdef.hpp> -#include <uhd/rfnoc/constants.hpp> -#include <boost/shared_ptr.hpp> #include <stdint.h> +#include <boost/shared_ptr.hpp> -namespace uhd { - namespace rfnoc { - // Forward declarations - class ctrl_iface; - namespace nocscript { - class block_iface; - } +namespace uhd { namespace rfnoc { +// Forward declarations +class ctrl_iface; +namespace nocscript { +class block_iface; +} // TODO: Move this out of public section struct make_args_t { - make_args_t(const std::string &key="") : - device_index(0), - block_name(""), - block_key(key) - {} + make_args_t(const std::string& key = "") + : device_index(0), block_name(""), block_key(key) + { + } //! A valid interface that allows us to read and write registers std::map<size_t, boost::shared_ptr<ctrl_iface> > ctrl_ifaces; @@ -58,25 +56,21 @@ struct make_args_t //! This macro must be put in the public section of an RFNoC // block class -#define UHD_RFNOC_BLOCK_OBJECT(class_name) \ - typedef boost::shared_ptr< class_name > sptr; +#define UHD_RFNOC_BLOCK_OBJECT(class_name) typedef boost::shared_ptr<class_name> sptr; //! Shorthand for block constructor #define UHD_RFNOC_BLOCK_CONSTRUCTOR(CLASS_NAME) \ - CLASS_NAME##_impl( \ - const make_args_t &make_args \ - ) : block_ctrl_base(make_args) + CLASS_NAME##_impl(const make_args_t& make_args) : block_ctrl_base(make_args) //! This macro must be placed inside a block implementation file // after the class definition -#define UHD_RFNOC_BLOCK_REGISTER(CLASS_NAME, BLOCK_NAME) \ - block_ctrl_base::sptr CLASS_NAME##_make( \ - const make_args_t &make_args \ - ) { \ - return block_ctrl_base::sptr(new CLASS_NAME##_impl(make_args)); \ - } \ - UHD_STATIC_BLOCK(register_rfnoc_##CLASS_NAME) \ - { \ +#define UHD_RFNOC_BLOCK_REGISTER(CLASS_NAME, BLOCK_NAME) \ + block_ctrl_base::sptr CLASS_NAME##_make(const make_args_t& make_args) \ + { \ + return block_ctrl_base::sptr(new CLASS_NAME##_impl(make_args)); \ + } \ + UHD_STATIC_BLOCK(register_rfnoc_##CLASS_NAME) \ + { \ uhd::rfnoc::block_ctrl_base::register_block(&CLASS_NAME##_make, BLOCK_NAME); \ } @@ -97,7 +91,7 @@ public: * Types **********************************************************************/ typedef boost::shared_ptr<block_ctrl_base> sptr; - typedef boost::function<sptr(const make_args_t &)> make_t; + typedef boost::function<sptr(const make_args_t&)> make_t; /*********************************************************************** * Factory functions @@ -113,7 +107,7 @@ public: * \param name A unique block name, e.g. 'FFT'. If a block has this block name, * it will use \p make to generate the block controller class. */ - static void register_block(const make_t &make, const std::string &name); + static void register_block(const make_t& make, const std::string& name); /*! * \brief Create a block controller class given a NoC-ID or a block name. @@ -129,7 +123,7 @@ public: * \param noc_id The 64-Bit NoC-ID. * \return a shared pointer to a new device instance */ - static sptr make(const make_args_t &make_args, uint64_t noc_id = ~0); + static sptr make(const make_args_t& make_args, uint64_t noc_id = ~0); /*********************************************************************** * Block Communication and Control @@ -139,15 +133,21 @@ public: /*! Returns the 16-Bit address for this block. */ - uint32_t get_address(size_t block_port=0); + uint32_t get_address(size_t block_port = 0); /*! Returns the unique block ID for this block (e.g. "0/FFT_1"). */ - block_id_t get_block_id() const { return _block_id; }; + block_id_t get_block_id() const + { + return _block_id; + }; /*! Shorthand for get_block_id().to_string() */ - std::string unique_id() const { return _block_id.to_string(); }; + std::string unique_id() const + { + return _block_id.to_string(); + }; /*********************************************************************** * FPGA control & communication @@ -178,7 +178,7 @@ public: * \throw uhd::key_error if \p reg is not a valid register name * */ - void sr_write(const std::string ®, const uint32_t data, const size_t port = 0); + void sr_write(const std::string& reg, const uint32_t data, const size_t port = 0); /*! Allows reading one register on the settings bus (64-Bit version). * @@ -221,7 +221,7 @@ public: * \returns the readback value. * \throws uhd::key_error if \p reg is not a valid register name */ - uint64_t user_reg_read64(const std::string ®, const size_t port = 0); + uint64_t user_reg_read64(const std::string& reg, const size_t port = 0); /*! Allows reading one user-defined register (32-Bit version). * @@ -247,7 +247,7 @@ public: * \throws uhd::key_error if \p reg is not a valid register name * \param port Port from which to read */ - uint32_t user_reg_read32(const std::string ®, const size_t port = 0); + uint32_t user_reg_read32(const std::string& reg, const size_t port = 0); /*! Sets a command time for all future command packets. @@ -255,7 +255,7 @@ public: * \throws uhd::assertion_error if the underlying interface does not * actually support timing. */ - void set_command_time(const time_spec_t &time_spec, const size_t port = ANY_PORT); + void set_command_time(const time_spec_t& time_spec, const size_t port = ANY_PORT); /*! Returns the current command time for all future command packets. * @@ -307,15 +307,16 @@ public: * Note that this function will silently ignore any keys in \p args that * aren't already registered as block arguments. */ - void set_args(const uhd::device_addr_t &args, const size_t port = 0); + void set_args(const uhd::device_addr_t& args, const size_t port = 0); //! Set a specific block argument. \p val is converted to the corresponding // data type using by looking up its type in the block definition. - void set_arg(const std::string &key, const std::string &val, const size_t port = 0); + void set_arg(const std::string& key, const std::string& val, const size_t port = 0); //! Direct access to set a block argument. template <typename T> - void set_arg(const std::string &key, const T &val, const size_t port = 0) { + void set_arg(const std::string& key, const T& val, const size_t port = 0) + { _tree->access<T>(get_arg_path(key, port) / "value").set(val); } @@ -323,40 +324,40 @@ public: uhd::device_addr_t get_args(const size_t port = 0) const; //! Return a single block argument in string format. - std::string get_arg(const std::string &key, const size_t port = 0) const; + std::string get_arg(const std::string& key, const size_t port = 0) const; //! Direct access to get a block argument. - template <typename T> - T get_arg(const std::string &key, const size_t port = 0) const { + template <typename T> T get_arg(const std::string& key, const size_t port = 0) const + { return _tree->access<T>(get_arg_path(key, port) / "value").get(); } - std::string get_arg_type(const std::string &key, const size_t port = 0) const; + std::string get_arg_type(const std::string& key, const size_t port = 0) const; protected: /*********************************************************************** * Structors **********************************************************************/ - block_ctrl_base(void) {}; // To allow pure virtual (interface) sub-classes + block_ctrl_base(void){}; // To allow pure virtual (interface) sub-classes virtual ~block_ctrl_base(); /*! Constructor. This is only called from the internal block factory! * * \param make_args All arguments to this constructor are passed in this object. - * Its details are subject to change. Use the UHD_RFNOC_BLOCK_CONSTRUCTOR() - * macro to set up your block's constructor in a portable fashion. + * Its details are subject to change. Use the + * UHD_RFNOC_BLOCK_CONSTRUCTOR() macro to set up your block's constructor in a + * portable fashion. */ - block_ctrl_base( - const make_args_t &make_args - ); + block_ctrl_base(const make_args_t& make_args); /*********************************************************************** * Helpers **********************************************************************/ - stream_sig_t _resolve_port_def(const blockdef::port_t &port_def) const; + stream_sig_t _resolve_port_def(const blockdef::port_t& port_def) const; //! Return the property tree path to a block argument \p key on \p port - uhd::fs_path get_arg_path(const std::string &key, size_t port = 0) const { + uhd::fs_path get_arg_path(const std::string& key, size_t port = 0) const + { return _root_path / "args" / port / key; }; @@ -373,7 +374,8 @@ protected: //! Override this function if your block needs to specially handle // setting the command time - virtual void _set_command_time(const time_spec_t &time_spec, const size_t port = ANY_PORT); + virtual void _set_command_time( + const time_spec_t& time_spec, const size_t port = ANY_PORT); /*********************************************************************** * Protected members **********************************************************************/ @@ -389,11 +391,9 @@ protected: private: //! Helper function to initialize the port definition nodes in the prop tree - void _init_port_defs( - const std::string &direction, - blockdef::ports_t ports, - const size_t first_port_index=0 - ); + void _init_port_defs(const std::string& direction, + blockdef::ports_t ports, + const size_t first_port_index = 0); //! Helper function to initialize the block args (used by ctor only) void _init_block_args(); diff --git a/host/include/uhd/rfnoc/block_id.hpp b/host/include/uhd/rfnoc/block_id.hpp index 126f3be25..8c4884807 100644 --- a/host/include/uhd/rfnoc/block_id.hpp +++ b/host/include/uhd/rfnoc/block_id.hpp @@ -14,187 +14,223 @@ #include <string> namespace uhd { - struct fs_path; - - namespace rfnoc { - - /*! - * Identifies an RFNoC block. - * - * An RFNoC block ID is a string such as: 0/FFT_1 - * - * The rules for formatting such a string are: - * - * DEVICE/BLOCKNAME_COUNTER - * - * DEVICE: Identifies the device (usually the motherboard index) - * BLOCKNAME: A name given to this block - * COUNTER: If is are more than one block with a BLOCKNAME, this counts up. - * - * So, 0/FFT_1 means we're addressing the second block called FFT - * on the first device. - * - * This class can represent these block IDs. - */ - class UHD_RFNOC_API block_id_t - { - public: - block_id_t(); - block_id_t(const std::string &block_str); - //! \param device_no Device number - //! \param block_name Block name - //! \param block_ctr Which block of this type is this on this device? - block_id_t(const size_t device_no, const std::string &block_name, const size_t block_ctr=0); - - //! Return a string like this: "0/FFT_1" (includes all components, if set) - std::string to_string() const; - - //! Check if a given string is valid as a block name. - // - // Note: This only applies to the block *name*, not the entire block ID. - // Examples: - // * is_valid_blockname("FFT") will return true. - // * is_valid_blockname("FIR_Filter") will return false, because an underscore - // is not allowed in a block name. - // - // Internally, this matches the string with uhd::rfnoc::VALID_BLOCKNAME_REGEX. - static bool is_valid_blockname(const std::string &block_name); - - //! Check if a given string is valid as a block ID. - // - // Note: This does necessary require a complete complete ID. If this returns - // true, then it is a valid input for block_id_t::match(). - // - // Examples: - // * is_valid_block_id("FFT") will return true. - // * is_valid_block_id("0/Filter_1") will return true. - // * is_valid_block_id("0/Filter_Foo") will return false. - // - // Internally, this matches the string with uhd::rfnoc::VALID_BLOCKID_REGEX. - static bool is_valid_block_id(const std::string &block_id); - - //! Check if block_str matches this block. - // - // A match is a less strict version of equality. - // Less specific block IDs will match more specific ones, - // e.g. "FFT" will match "0/FFT_1", "1/FFT_2", etc. - // "FFT_1" will only match the former, etc. - bool match(const std::string &block_str); - - // Getters - - //! Short for to_string() - std::string get() const { return to_string(); }; - - //! Like get(), but only returns the local part ("FFT_1") - std::string get_local() const; - - //! Returns the property tree root for this block (e.g. "/mboards/0/xbar/FFT_1/") - uhd::fs_path get_tree_root() const; - - //! Return device number - size_t get_device_no() const { return _device_no; }; - - //! Return block count - size_t get_block_count() const { return _block_ctr; }; - - //! Return block name - std::string get_block_name() const { return _block_name; }; - - // Setters - - //! Set from string such as "0/FFT_1", "FFT_0", ... - // Returns true if successful (i.e. if string valid) - bool set(const std::string &new_name); - - //! Sets from individual compontents, like calling set_device_no(), set_block_name() - // and set_block_count() one after another, only if \p block_name is invalid, stops - // and returns false before chaning anything - bool set(const size_t device_no, const std::string &block_name, const size_t block_ctr=0); - - //! Set the device number - void set_device_no(size_t device_no) { _device_no = device_no; }; - - //! Set the block name. Will return false if invalid block string. - bool set_block_name(const std::string &block_name); - - //! Set the block count. - void set_block_count(size_t count) { _block_ctr = count; }; - - // Overloaded operators - - //! Assignment: Works like set(std::string) - block_id_t operator = (const std::string &new_name) { - set(new_name); - return *this; - } - - bool operator == (const block_id_t &block_id) const { - return (_device_no == block_id.get_device_no()) - and (_block_name == block_id.get_block_name()) - and (_block_ctr == block_id.get_block_count()); - } - - bool operator != (const block_id_t &block_id) const { - return not (*this == block_id); - } - - bool operator < (const block_id_t &block_id) const { - return ( - _device_no < block_id.get_device_no() - or (_device_no == block_id.get_device_no() and _block_name < block_id.get_block_name()) - or (_device_no == block_id.get_device_no() and _block_name == block_id.get_block_name() and _block_ctr < block_id.get_block_count()) - ); - } - - bool operator > (const block_id_t &block_id) const { - return ( - _device_no > block_id.get_device_no() - or (_device_no == block_id.get_device_no() and _block_name > block_id.get_block_name()) - or (_device_no == block_id.get_device_no() and _block_name == block_id.get_block_name() and _block_ctr > block_id.get_block_count()) - ); - } - - //! Check if a string matches the entire block ID (not like match()) - bool operator == (const std::string &block_id_str) const { - return get() == block_id_str; - } - - //! Check if a string matches the entire block ID (not like match()) - bool operator == (const char *block_id_str) const { - std::string comp = std::string(block_id_str); - return *this == comp; - } - - //! Type-cast operator does the same as to_string() - operator std::string() const { - return to_string(); - } - - //! Increment the block count ("FFT_1" -> "FFT_2") - block_id_t operator++() { - _block_ctr++; - return *this; - } - - //! Increment the block count ("FFT_1" -> "FFT_2") - block_id_t operator++(int) { - _block_ctr++; - return *this; - } - - private: - size_t _device_no; - std::string _block_name; - size_t _block_ctr; +struct fs_path; + +namespace rfnoc { + +/*! + * Identifies an RFNoC block. + * + * An RFNoC block ID is a string such as: 0/FFT_1 + * + * The rules for formatting such a string are: + * + * DEVICE/BLOCKNAME_COUNTER + * + * DEVICE: Identifies the device (usually the motherboard index) + * BLOCKNAME: A name given to this block + * COUNTER: If is are more than one block with a BLOCKNAME, this counts up. + * + * So, 0/FFT_1 means we're addressing the second block called FFT + * on the first device. + * + * This class can represent these block IDs. + */ +class UHD_RFNOC_API block_id_t +{ +public: + block_id_t(); + block_id_t(const std::string& block_str); + //! \param device_no Device number + //! \param block_name Block name + //! \param block_ctr Which block of this type is this on this device? + block_id_t(const size_t device_no, + const std::string& block_name, + const size_t block_ctr = 0); + + //! Return a string like this: "0/FFT_1" (includes all components, if set) + std::string to_string() const; + + //! Check if a given string is valid as a block name. + // + // Note: This only applies to the block *name*, not the entire block ID. + // Examples: + // * is_valid_blockname("FFT") will return true. + // * is_valid_blockname("FIR_Filter") will return false, because an underscore + // is not allowed in a block name. + // + // Internally, this matches the string with uhd::rfnoc::VALID_BLOCKNAME_REGEX. + static bool is_valid_blockname(const std::string& block_name); + + //! Check if a given string is valid as a block ID. + // + // Note: This does necessary require a complete complete ID. If this returns + // true, then it is a valid input for block_id_t::match(). + // + // Examples: + // * is_valid_block_id("FFT") will return true. + // * is_valid_block_id("0/Filter_1") will return true. + // * is_valid_block_id("0/Filter_Foo") will return false. + // + // Internally, this matches the string with uhd::rfnoc::VALID_BLOCKID_REGEX. + static bool is_valid_block_id(const std::string& block_id); + + //! Check if block_str matches this block. + // + // A match is a less strict version of equality. + // Less specific block IDs will match more specific ones, + // e.g. "FFT" will match "0/FFT_1", "1/FFT_2", etc. + // "FFT_1" will only match the former, etc. + bool match(const std::string& block_str); + + // Getters + + //! Short for to_string() + std::string get() const + { + return to_string(); + }; + + //! Like get(), but only returns the local part ("FFT_1") + std::string get_local() const; + + //! Returns the property tree root for this block (e.g. "/mboards/0/xbar/FFT_1/") + uhd::fs_path get_tree_root() const; + + //! Return device number + size_t get_device_no() const + { + return _device_no; + }; + + //! Return block count + size_t get_block_count() const + { + return _block_ctr; + }; + + //! Return block name + std::string get_block_name() const + { + return _block_name; + }; + + // Setters + + //! Set from string such as "0/FFT_1", "FFT_0", ... + // Returns true if successful (i.e. if string valid) + bool set(const std::string& new_name); + + //! Sets from individual compontents, like calling set_device_no(), set_block_name() + // and set_block_count() one after another, only if \p block_name is invalid, stops + // and returns false before chaning anything + bool set(const size_t device_no, + const std::string& block_name, + const size_t block_ctr = 0); + + //! Set the device number + void set_device_no(size_t device_no) + { + _device_no = device_no; }; - //! Shortcut for << block_id.to_string() - inline std::ostream& operator<< (std::ostream& out, block_id_t block_id) { - out << block_id.to_string(); - return out; + //! Set the block name. Will return false if invalid block string. + bool set_block_name(const std::string& block_name); + + //! Set the block count. + void set_block_count(size_t count) + { + _block_ctr = count; + }; + + // Overloaded operators + + //! Assignment: Works like set(std::string) + block_id_t operator=(const std::string& new_name) + { + set(new_name); + return *this; + } + + bool operator==(const block_id_t& block_id) const + { + return (_device_no == block_id.get_device_no()) + and (_block_name == block_id.get_block_name()) + and (_block_ctr == block_id.get_block_count()); + } + + bool operator!=(const block_id_t& block_id) const + { + return not(*this == block_id); + } + + bool operator<(const block_id_t& block_id) const + { + return (_device_no < block_id.get_device_no() + or (_device_no == block_id.get_device_no() + and _block_name < block_id.get_block_name()) + or (_device_no == block_id.get_device_no() + and _block_name == block_id.get_block_name() + and _block_ctr < block_id.get_block_count())); + } + + bool operator>(const block_id_t& block_id) const + { + return (_device_no > block_id.get_device_no() + or (_device_no == block_id.get_device_no() + and _block_name > block_id.get_block_name()) + or (_device_no == block_id.get_device_no() + and _block_name == block_id.get_block_name() + and _block_ctr > block_id.get_block_count())); + } + + //! Check if a string matches the entire block ID (not like match()) + bool operator==(const std::string& block_id_str) const + { + return get() == block_id_str; + } + + //! Check if a string matches the entire block ID (not like match()) + bool operator==(const char* block_id_str) const + { + std::string comp = std::string(block_id_str); + return *this == comp; + } + + //! Type-cast operator does the same as to_string() + operator std::string() const + { + return to_string(); + } + + //! Increment the block count ("FFT_1" -> "FFT_2") + block_id_t operator++() + { + _block_ctr++; + return *this; + } + + //! Increment the block count ("FFT_1" -> "FFT_2") + block_id_t operator++(int) + { + _block_ctr++; + return *this; } -}} //namespace uhd::rfnoc +private: + size_t _device_no; + std::string _block_name; + size_t _block_ctr; +}; + +//! Shortcut for << block_id.to_string() +inline std::ostream& operator<<(std::ostream& out, block_id_t block_id) +{ + out << block_id.to_string(); + return out; +} + +} // namespace rfnoc +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_BLOCK_ID_HPP */ diff --git a/host/include/uhd/rfnoc/blockdef.hpp b/host/include/uhd/rfnoc/blockdef.hpp index 43845aa7d..30c5219e1 100644 --- a/host/include/uhd/rfnoc/blockdef.hpp +++ b/host/include/uhd/rfnoc/blockdef.hpp @@ -8,12 +8,12 @@ #ifndef INCLUDED_LIBUHD_RFNOC_BLOCKDEF_HPP #define INCLUDED_LIBUHD_RFNOC_BLOCKDEF_HPP -#include <stdint.h> -#include <boost/enable_shared_from_this.hpp> #include <uhd/config.hpp> #include <uhd/types/device_addr.hpp> -#include <vector> +#include <stdint.h> +#include <boost/enable_shared_from_this.hpp> #include <set> +#include <vector> namespace uhd { namespace rfnoc { @@ -31,17 +31,18 @@ public: // to describe what kind of connection is allowed for this port. // // All the keys listed in PORT_ARGS will be available in this class. - class port_t : public uhd::dict<std::string, std::string> { - public: + class port_t : public uhd::dict<std::string, std::string> + { + public: //! A list of args a port can have. static const device_addr_t PORT_ARGS; port_t(); //! Checks if the value at \p key is a variable (e.g. '$fftlen') - bool is_variable(const std::string &key) const; + bool is_variable(const std::string& key) const; //! Checks if the value at \p key is a keyword (e.g. '%vlen') - bool is_keyword(const std::string &key) const; + bool is_keyword(const std::string& key) const; //! Basic validity check of this port definition. Variables and // keywords are not resolved. bool is_valid() const; @@ -51,8 +52,9 @@ public: typedef std::vector<port_t> ports_t; //! Describes arguments in a block definition. - class arg_t : public uhd::dict<std::string, std::string> { - public: + class arg_t : public uhd::dict<std::string, std::string> + { + public: //! A list of args an argument can have. static const device_addr_t ARG_ARGS; static const std::set<std::string> VALID_TYPES; @@ -63,7 +65,6 @@ public: bool is_valid() const; //! Returns a string with the most important keys std::string to_string() const; - }; typedef std::vector<arg_t> args_t; @@ -92,7 +93,7 @@ public: //! Return the one NoC that is valid for this block virtual uint64_t noc_id() const = 0; - virtual ports_t get_input_ports() = 0; + virtual ports_t get_input_ports() = 0; virtual ports_t get_output_ports() = 0; //! Returns the full list of port numbers used diff --git a/host/include/uhd/rfnoc/constants.hpp b/host/include/uhd/rfnoc/constants.hpp index 8c97fa220..9d9295809 100644 --- a/host/include/uhd/rfnoc/constants.hpp +++ b/host/include/uhd/rfnoc/constants.hpp @@ -9,12 +9,11 @@ #define INCLUDED_LIBUHD_RFNOC_CONSTANTS_HPP #include <uhd/types/dict.hpp> -#include <boost/assign/list_of.hpp> #include <stdint.h> +#include <boost/assign/list_of.hpp> #include <string> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { // All these configure the XML reader //! Where the RFNoC block/component definition files lie, relative to UHD_PKG_DIR @@ -24,11 +23,11 @@ static const std::string XML_PATH_ENV = "UHD_RFNOC_DIR"; //! If the block name can't be automatically detected, this name is used static const std::string DEFAULT_BLOCK_NAME = "Block"; -static const uint64_t DEFAULT_NOC_ID = 0xFFFFFFFFFFFFFFFF; -static const size_t NOC_SHELL_COMPAT_MAJOR = 5; -static const size_t NOC_SHELL_COMPAT_MINOR = 0; +static const uint64_t DEFAULT_NOC_ID = 0xFFFFFFFFFFFFFFFF; +static const size_t NOC_SHELL_COMPAT_MAJOR = 5; +static const size_t NOC_SHELL_COMPAT_MINOR = 0; -static const size_t MAX_PACKET_SIZE = 8000; // bytes +static const size_t MAX_PACKET_SIZE = 8000; // bytes static const size_t DEFAULT_PACKET_SIZE = 1456; // bytes // One line in FPGA is 64 Bits @@ -44,57 +43,60 @@ static const size_t DEFAULT_FC_TX_RESPONSE_FREQ = 8; // ACKs per flow control wi // Why not 100% full? Because we need to have some headroom to account for the inaccuracy // when computing the window size. We compute the flow control window based on the frame // size but the buffer can have overhead due to things like UDP headers, page alignment, -// housekeeping info, etc. This number has to be transport agnostic so 20% of headroom is safe. +// housekeeping info, etc. This number has to be transport agnostic so 20% of headroom is +// safe. static const double DEFAULT_FC_RX_SW_BUFF_FULL_FACTOR = 0.80; // Common settings registers. -static const uint32_t SR_FLOW_CTRL_BYTES_PER_ACK = 1; -static const uint32_t SR_FLOW_CTRL_WINDOW_SIZE = 2; -static const uint32_t SR_FLOW_CTRL_EN = 3; -static const uint32_t SR_ERROR_POLICY = 4; -static const uint32_t SR_BLOCK_SID = 5; // TODO rename to SRC_SID -static const uint32_t SR_NEXT_DST_SID = 6; -static const uint32_t SR_RESP_IN_DST_SID = 7; -static const uint32_t SR_RESP_OUT_DST_SID = 8; -static const uint32_t SR_FLOW_CTRL_PKT_LIMIT = 9; - -static const uint32_t SR_READBACK_ADDR = 124; -static const uint32_t SR_READBACK = 127; - -static const uint32_t SR_CLEAR_RX_FC = 125; -static const uint32_t SR_CLEAR_TX_FC = 126; +static const uint32_t SR_FLOW_CTRL_BYTES_PER_ACK = 1; +static const uint32_t SR_FLOW_CTRL_WINDOW_SIZE = 2; +static const uint32_t SR_FLOW_CTRL_EN = 3; +static const uint32_t SR_ERROR_POLICY = 4; +static const uint32_t SR_BLOCK_SID = 5; // TODO rename to SRC_SID +static const uint32_t SR_NEXT_DST_SID = 6; +static const uint32_t SR_RESP_IN_DST_SID = 7; +static const uint32_t SR_RESP_OUT_DST_SID = 8; +static const uint32_t SR_FLOW_CTRL_PKT_LIMIT = 9; + +static const uint32_t SR_READBACK_ADDR = 124; +static const uint32_t SR_READBACK = 127; + +static const uint32_t SR_CLEAR_RX_FC = 125; +static const uint32_t SR_CLEAR_TX_FC = 126; //! Settings register readback enum settingsbus_reg_t { - SR_READBACK_REG_ID = 0, - SR_READBACK_REG_GLOBAL_PARAMS = 1, - SR_READBACK_REG_FIFOSIZE = 2, // fifo size - SR_READBACK_REG_MTU = 3, + SR_READBACK_REG_ID = 0, + SR_READBACK_REG_GLOBAL_PARAMS = 1, + SR_READBACK_REG_FIFOSIZE = 2, // fifo size + SR_READBACK_REG_MTU = 3, SR_READBACK_REG_BLOCKPORT_SIDS = 4, - SR_READBACK_REG_USER = 5, - SR_READBACK_COMPAT = 6 + SR_READBACK_REG_USER = 5, + SR_READBACK_COMPAT = 6 }; // AXI stream configuration bus (output master bus of axi wrapper) registers -static const uint32_t AXI_WRAPPER_BASE = 128; -static const uint32_t AXIS_CONFIG_BUS = AXI_WRAPPER_BASE+1; // tdata with tvalid asserted -static const uint32_t AXIS_CONFIG_BUS_TLAST = AXI_WRAPPER_BASE+2; // tdata with tvalid & tlast asserted +static const uint32_t AXI_WRAPPER_BASE = 128; +static const uint32_t AXIS_CONFIG_BUS = + AXI_WRAPPER_BASE + 1; // tdata with tvalid asserted +static const uint32_t AXIS_CONFIG_BUS_TLAST = + AXI_WRAPPER_BASE + 2; // tdata with tvalid & tlast asserted static const size_t CMD_FIFO_SIZE = 128; // Lines == multiples of 8 bytes // Named settings registers -static const uhd::dict<std::string, uint32_t> DEFAULT_NAMED_SR = boost::assign::map_list_of - ("AXIS_CONFIG_BUS", AXIS_CONFIG_BUS) - ("AXIS_CONFIG_BUS_TLAST", AXIS_CONFIG_BUS_TLAST) -; +static const uhd::dict<std::string, uint32_t> DEFAULT_NAMED_SR = + boost::assign::map_list_of("AXIS_CONFIG_BUS", AXIS_CONFIG_BUS)( + "AXIS_CONFIG_BUS_TLAST", AXIS_CONFIG_BUS_TLAST); // Block ports -static const size_t ANY_PORT = size_t(~0); +static const size_t ANY_PORT = size_t(~0); static const size_t MAX_NUM_PORTS = 16; // Regular expressions static const std::string VALID_BLOCKNAME_REGEX = "[A-Za-z][A-Za-z0-9]*"; -static const std::string VALID_BLOCKID_REGEX = "(?:(\\d+)(?:/))?([A-Za-z][A-Za-z0-9]*)(?:(?:_)(\\d\\d?))?"; +static const std::string VALID_BLOCKID_REGEX = + "(?:(\\d+)(?:/))?([A-Za-z][A-Za-z0-9]*)(?:(?:_)(\\d\\d?))?"; }} /* namespace uhd::rfnoc */ diff --git a/host/include/uhd/rfnoc/ddc_block_ctrl.hpp b/host/include/uhd/rfnoc/ddc_block_ctrl.hpp index daca3b8d3..2a261db00 100644 --- a/host/include/uhd/rfnoc/ddc_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/ddc_block_ctrl.hpp @@ -8,13 +8,12 @@ #ifndef INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> -#include <uhd/rfnoc/sink_block_ctrl_base.hpp> #include <uhd/rfnoc/rate_node_ctrl.hpp> #include <uhd/rfnoc/scalar_node_ctrl.hpp> +#include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief DDC block controller * @@ -24,11 +23,10 @@ namespace uhd { * * It also includes a CORDIC component to shift signals in frequency. */ -class UHD_RFNOC_API ddc_block_ctrl : - public source_block_ctrl_base, - public sink_block_ctrl_base, - public rate_node_ctrl, - public scalar_node_ctrl +class UHD_RFNOC_API ddc_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base, + public rate_node_ctrl, + public scalar_node_ctrl { public: UHD_RFNOC_BLOCK_OBJECT(ddc_block_ctrl) diff --git a/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp b/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp index 74ab1ec15..093e2ef91 100644 --- a/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp @@ -8,11 +8,10 @@ #ifndef INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP #define INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Block controller for a DMA FIFO block. * @@ -24,13 +23,15 @@ namespace uhd { * bank. * */ -class UHD_RFNOC_API dma_fifo_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base +class UHD_RFNOC_API dma_fifo_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base { public: UHD_RFNOC_BLOCK_OBJECT(dma_fifo_block_ctrl) //! Configure the base address and depth of the FIFO (in bytes). - virtual void resize(const uint32_t base_addr, const uint32_t depth, const size_t chan) = 0; + virtual void resize( + const uint32_t base_addr, const uint32_t depth, const size_t chan) = 0; //! Returns the base address of the FIFO (in bytes). uint32_t get_base_addr(const size_t chan) const; diff --git a/host/include/uhd/rfnoc/duc_block_ctrl.hpp b/host/include/uhd/rfnoc/duc_block_ctrl.hpp index 13eac5812..b24f7af26 100644 --- a/host/include/uhd/rfnoc/duc_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/duc_block_ctrl.hpp @@ -8,13 +8,12 @@ #ifndef INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> -#include <uhd/rfnoc/sink_block_ctrl_base.hpp> #include <uhd/rfnoc/rate_node_ctrl.hpp> #include <uhd/rfnoc/scalar_node_ctrl.hpp> +#include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief DUC block controller * @@ -24,11 +23,10 @@ namespace uhd { * * It also includes a CORDIC component to shift signals in frequency. */ -class UHD_RFNOC_API duc_block_ctrl : - public source_block_ctrl_base, - public sink_block_ctrl_base, - public rate_node_ctrl, - public scalar_node_ctrl +class UHD_RFNOC_API duc_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base, + public rate_node_ctrl, + public scalar_node_ctrl { public: UHD_RFNOC_BLOCK_OBJECT(duc_block_ctrl) @@ -38,4 +36,3 @@ public: }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP */ - diff --git a/host/include/uhd/rfnoc/fir_block_ctrl.hpp b/host/include/uhd/rfnoc/fir_block_ctrl.hpp index 3fd93620d..67a6a958b 100644 --- a/host/include/uhd/rfnoc/fir_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/fir_block_ctrl.hpp @@ -7,11 +7,10 @@ #ifndef INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP #define INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Block controller for the standard FIR RFNoC block. * @@ -24,7 +23,8 @@ namespace uhd { * It will perform one FFT operation per incoming packet, treating it * as a vector of samples. */ -class UHD_RFNOC_API fir_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base +class UHD_RFNOC_API fir_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base { public: UHD_RFNOC_BLOCK_OBJECT(fir_block_ctrl) @@ -34,7 +34,7 @@ public: // The length of \p taps must correspond the number of taps // in this block. If it's shorter, zeros will be padded. // If it's longer, throws a uhd::value_error. - virtual void set_taps(const std::vector<int> &taps) = 0; + virtual void set_taps(const std::vector<int>& taps) = 0; //! Returns the number of filter taps in this block. virtual size_t get_n_taps() const = 0; diff --git a/host/include/uhd/rfnoc/graph.hpp b/host/include/uhd/rfnoc/graph.hpp index f6620d39b..b3372e389 100644 --- a/host/include/uhd/rfnoc/graph.hpp +++ b/host/include/uhd/rfnoc/graph.hpp @@ -8,9 +8,9 @@ #ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_HPP #define INCLUDED_LIBUHD_RFNOC_GRAPH_HPP -#include <boost/noncopyable.hpp> #include <uhd/rfnoc/block_id.hpp> #include <uhd/types/sid.hpp> +#include <boost/noncopyable.hpp> namespace uhd { namespace rfnoc { @@ -19,7 +19,8 @@ class graph : boost::noncopyable public: typedef boost::shared_ptr<uhd::rfnoc::graph> sptr; - /*! Connect a RFNOC block with block ID \p src_block to another with block ID \p dst_block. + /*! Connect a RFNOC block with block ID \p src_block to another with block ID \p + * dst_block. * * This will: * - Check if this connection is valid (IO signatures, see if types match) @@ -27,22 +28,17 @@ public: * - Configure SID for the upstream block * - Register the upstream block in the downstream block */ - virtual void connect( - const block_id_t &src_block, - size_t src_block_port, - const block_id_t &dst_block, - size_t dst_block_port, - const size_t pkt_size = 0 - ) = 0; + virtual void connect(const block_id_t& src_block, + size_t src_block_port, + const block_id_t& dst_block, + size_t dst_block_port, + const size_t pkt_size = 0) = 0; /*! Shorthand for connect(). * * Using default ports for both source and destination. */ - virtual void connect( - const block_id_t &src_block, - const block_id_t &dst_block - ) = 0; + virtual void connect(const block_id_t& src_block, const block_id_t& dst_block) = 0; /*! Anonymous connection. * @@ -53,13 +49,11 @@ public: * \param dst_sid SID to route traffic to * \param buf_size_dst_bytes Destination window buffer in bytes */ - virtual void connect_src( - const block_id_t &src_block, - const size_t src_block_port, - const uhd::sid_t dst_sid, - const size_t buf_size_dst_bytes, - const size_t pkt_size_ - ) = 0; + virtual void connect_src(const block_id_t& src_block, + const size_t src_block_port, + const uhd::sid_t dst_sid, + const size_t buf_size_dst_bytes, + const size_t pkt_size_) = 0; /*! Anonymous connection * @@ -69,15 +63,13 @@ public: * \param dst_block_port Destination (sink) block port * \param bytes_per_ack Flow control frequency in bytes */ - virtual void connect_sink( - const block_id_t &sink_block, - const size_t dst_block_port, - const size_t bytes_per_ack - ) = 0; + virtual void connect_sink(const block_id_t& sink_block, + const size_t dst_block_port, + const size_t bytes_per_ack) = 0; virtual std::string get_name() const = 0; }; -}}; /* name space uhd::rfnoc */ +}}; // namespace uhd::rfnoc #endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_HPP */ diff --git a/host/include/uhd/rfnoc/node_ctrl_base.hpp b/host/include/uhd/rfnoc/node_ctrl_base.hpp index 791f74afd..0fed28bed 100644 --- a/host/include/uhd/rfnoc/node_ctrl_base.hpp +++ b/host/include/uhd/rfnoc/node_ctrl_base.hpp @@ -8,19 +8,18 @@ #ifndef INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP #define INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP -#include <uhd/types/device_addr.hpp> #include <uhd/rfnoc/constants.hpp> +#include <uhd/types/device_addr.hpp> #include <uhd/utils/log.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/utility.hpp> +#include <stdint.h> #include <boost/enable_shared_from_this.hpp> #include <boost/function.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> #include <map> #include <set> -#include <stdint.h> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { #define UHD_RFNOC_BLOCK_TRACE() UHD_LOGGER_TRACE("RFNOC") @@ -28,7 +27,8 @@ namespace uhd { * */ class UHD_RFNOC_API node_ctrl_base; -class node_ctrl_base : boost::noncopyable, public boost::enable_shared_from_this<node_ctrl_base> +class node_ctrl_base : boost::noncopyable, + public boost::enable_shared_from_this<node_ctrl_base> { public: /*********************************************************************** @@ -36,8 +36,8 @@ public: **********************************************************************/ typedef boost::shared_ptr<node_ctrl_base> sptr; typedef boost::weak_ptr<node_ctrl_base> wptr; - typedef std::map< size_t, wptr > node_map_t; - typedef std::pair< size_t, wptr > node_map_pair_t; + typedef std::map<size_t, wptr> node_map_t; + typedef std::pair<size_t, wptr> node_map_pair_t; /*********************************************************************** * Node control @@ -52,8 +52,14 @@ public: */ virtual void clear(); - node_map_t list_downstream_nodes() { return _downstream_nodes; }; - node_map_t list_upstream_nodes() { return _upstream_nodes; }; + node_map_t list_downstream_nodes() + { + return _downstream_nodes; + }; + node_map_t list_upstream_nodes() + { + return _upstream_nodes; + }; /*! Disconnect this node from all neighbouring nodes. */ @@ -109,7 +115,8 @@ public: * Search only goes downstream. */ template <typename T> - UHD_INLINE std::vector< boost::shared_ptr<T> > find_downstream_node(bool active_only = false) + UHD_INLINE std::vector<boost::shared_ptr<T> > find_downstream_node( + bool active_only = false) { return _find_child_node<T, true>(active_only); } @@ -117,7 +124,8 @@ public: /*! Same as find_downstream_node(), but only search upstream. */ template <typename T> - UHD_INLINE std::vector< boost::shared_ptr<T> > find_upstream_node(bool active_only = false) + UHD_INLINE std::vector<boost::shared_ptr<T> > find_upstream_node( + bool active_only = false) { return _find_child_node<T, false>(active_only); } @@ -136,22 +144,26 @@ public: */ template <typename T, typename value_type> UHD_INLINE value_type find_downstream_unique_property( - boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property, - value_type null_value, - const std::set< boost::shared_ptr<T> > &exclude_nodes=std::set< boost::shared_ptr<T> >() - ) { - return _find_unique_property<T, value_type, true>(get_property, null_value, exclude_nodes); + boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property, + value_type null_value, + const std::set<boost::shared_ptr<T> >& exclude_nodes = + std::set<boost::shared_ptr<T> >()) + { + return _find_unique_property<T, value_type, true>( + get_property, null_value, exclude_nodes); } /*! Like find_downstream_unique_property(), but searches upstream. */ template <typename T, typename value_type> UHD_INLINE value_type find_upstream_unique_property( - boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property, - value_type null_value, - const std::set< boost::shared_ptr<T> > &exclude_nodes=std::set< boost::shared_ptr<T> >() - ) { - return _find_unique_property<T, value_type, false>(get_property, null_value, exclude_nodes); + boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property, + value_type null_value, + const std::set<boost::shared_ptr<T> >& exclude_nodes = + std::set<boost::shared_ptr<T> >()) + { + return _find_unique_property<T, value_type, false>( + get_property, null_value, exclude_nodes); } protected: @@ -159,7 +171,10 @@ protected: * Structors **********************************************************************/ node_ctrl_base(void) {} - virtual ~node_ctrl_base() { disconnect(); } + virtual ~node_ctrl_base() + { + disconnect(); + } /*********************************************************************** * Protected members @@ -204,9 +219,7 @@ protected: * See also uhd::rfnoc::source_node_ctrl::_register_downstream_node(). */ virtual void _register_downstream_node( - node_ctrl_base::sptr downstream_node, - size_t port - ); + node_ctrl_base::sptr downstream_node, size_t port); /*! Registers another node as upstream of this node, connected to a given port. * @@ -214,10 +227,7 @@ protected: * a source node. * See also uhd::rfnoc::sink_node_ctrl::_register_upstream_node(). */ - virtual void _register_upstream_node( - node_ctrl_base::sptr upstream_node, - size_t port - ); + virtual void _register_upstream_node(node_ctrl_base::sptr upstream_node, size_t port); private: /*! Implements the search algorithm for find_downstream_node() and @@ -229,7 +239,7 @@ private: * \param downstream Set to true if search goes downstream, false for upstream. */ template <typename T, bool downstream> - std::vector< boost::shared_ptr<T> > _find_child_node(bool active_only = false); + std::vector<boost::shared_ptr<T> > _find_child_node(bool active_only = false); /*! Implements the search algorithm for find_downstream_unique_property() and * find_upstream_unique_property(). @@ -241,10 +251,9 @@ private: */ template <typename T, typename value_type, bool downstream> value_type _find_unique_property( - boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property, - value_type NULL_VALUE, - const std::set< boost::shared_ptr<T> > &exclude_nodes - ); + boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property, + value_type NULL_VALUE, + const std::set<boost::shared_ptr<T> >& exclude_nodes); /*! Stores the remote port number of a downstream connection. */ diff --git a/host/include/uhd/rfnoc/null_block_ctrl.hpp b/host/include/uhd/rfnoc/null_block_ctrl.hpp index 18ff7cea1..1406fd219 100644 --- a/host/include/uhd/rfnoc/null_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/null_block_ctrl.hpp @@ -7,11 +7,10 @@ #ifndef INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Provide access to a 'null block'. * @@ -45,7 +44,7 @@ public: static const uint32_t SR_ENABLE_STREAM = 131; static const size_t DEFAULT_LINES_PER_PACKET = 32; - static const size_t BYTES_PER_LINE = 8; + static const size_t BYTES_PER_LINE = 8; //! Custom function to set the rate at which data is produced. // Note: This is 'cycles per line', so the bit rate is actually @@ -56,11 +55,11 @@ public: // \param The rate you want to set this to // \param The clock rate of this block's clock domain // \returns the actual line rate (will find closest possible). - virtual double set_line_rate(double rate, double clock_rate=166.6e6) = 0; + virtual double set_line_rate(double rate, double clock_rate = 166.6e6) = 0; //! Return the current line rate. Equivalent to reading line_rate/value // from the property tree. - virtual double get_line_rate(double clock_rate=166.6e6) const = 0; + virtual double get_line_rate(double clock_rate = 166.6e6) const = 0; }; /* class null_block_ctrl*/ diff --git a/host/include/uhd/rfnoc/radio_ctrl.hpp b/host/include/uhd/rfnoc/radio_ctrl.hpp index 28ba9264b..4f8f3bb1d 100644 --- a/host/include/uhd/rfnoc/radio_ctrl.hpp +++ b/host/include/uhd/rfnoc/radio_ctrl.hpp @@ -8,31 +8,29 @@ #ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP -#include <uhd/types/ranges.hpp> -#include <uhd/types/direction.hpp> -#include <uhd/rfnoc/source_block_ctrl_base.hpp> -#include <uhd/rfnoc/sink_block_ctrl_base.hpp> #include <uhd/rfnoc/rate_node_ctrl.hpp> -#include <uhd/rfnoc/tick_node_ctrl.hpp> #include <uhd/rfnoc/scalar_node_ctrl.hpp> +#include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/terminator_node_ctrl.hpp> +#include <uhd/rfnoc/tick_node_ctrl.hpp> +#include <uhd/types/direction.hpp> +#include <uhd/types/ranges.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Block controller for all RFNoC-based radio blocks */ -class UHD_RFNOC_API radio_ctrl : - public source_block_ctrl_base, - public sink_block_ctrl_base, - public rate_node_ctrl, - public tick_node_ctrl, - public terminator_node_ctrl +class UHD_RFNOC_API radio_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base, + public rate_node_ctrl, + public tick_node_ctrl, + public terminator_node_ctrl { public: UHD_RFNOC_BLOCK_OBJECT(radio_ctrl) - virtual ~radio_ctrl(){} + virtual ~radio_ctrl() {} //! A wildcard channel index @@ -69,7 +67,7 @@ public: * * \throws uhd::value_error if \p ant is not a valid value. */ - virtual void set_tx_antenna(const std::string &ant, const size_t chan) = 0; + virtual void set_tx_antenna(const std::string& ant, const size_t chan) = 0; /*! Return the selected RX antenna for channel \p chan. * @@ -81,7 +79,7 @@ public: * * \throws uhd::value_error if \p ant is not a valid value. */ - virtual void set_rx_antenna(const std::string &ant, const size_t chan) = 0; + virtual void set_rx_antenna(const std::string& ant, const size_t chan) = 0; /*! Return the current transmit LO frequency on channel \p chan. * @@ -163,10 +161,7 @@ public: * * \return The actual bandwidth value */ - virtual double set_tx_bandwidth( - const double bandwidth, - const size_t chan - ) = 0; + virtual double set_tx_bandwidth(const double bandwidth, const size_t chan) = 0; /*! Return the analog filter bandwidth channel \p chan * @@ -189,7 +184,7 @@ public: * time in alignment with a certain reference time, use * set_time_next_pps(). */ - virtual void set_time_now(const time_spec_t &time_spec) = 0; + virtual void set_time_now(const time_spec_t& time_spec) = 0; /*! Set the time registers at the next pps tick. * @@ -202,7 +197,7 @@ public: * * \param time_spec the time to latch into the timekeeper */ - virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; + virtual void set_time_next_pps(const time_spec_t& time_spec) = 0; /*! Get the current time in the timekeeper registers. * @@ -241,12 +236,10 @@ public: * \param value the new value for this GPIO bank * \param mask the bit mask to effect which pins are changed */ - virtual void set_gpio_attr( - const std::string &bank, - const std::string &attr, - const uint32_t value, - const uint32_t mask - ) = 0; + virtual void set_gpio_attr(const std::string& bank, + const std::string& attr, + const uint32_t value, + const uint32_t mask) = 0; /*! * Get a GPIO attribute on a particular GPIO bank. @@ -263,7 +256,7 @@ public: * \param attr the name of a GPIO attribute * \return the value set for this attribute */ - virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr) = 0; + virtual uint32_t get_gpio_attr(const std::string& bank, const std::string& attr) = 0; /************************************************************************** * LO Controls @@ -283,7 +276,8 @@ public: * \param chan the channel index 0 to N-1 * \return a vector of strings for possible settings */ - virtual std::vector<std::string> get_rx_lo_sources(const std::string &name, const size_t chan) = 0; + virtual std::vector<std::string> get_rx_lo_sources( + const std::string& name, const size_t chan) = 0; /*! * Get the LO frequency range of the RX LO. @@ -293,7 +287,8 @@ public: * \param chan the channel index 0 to N-1 * \return a frequency range object */ - virtual freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan) = 0; + virtual freq_range_t get_rx_lo_freq_range( + const std::string& name, const size_t chan) = 0; /*! * Set the LO source for a channel. @@ -304,7 +299,8 @@ public: * \param name the name of the LO stage to update * \param chan the channel index 0 to N-1 */ - virtual void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan) = 0; + virtual void set_rx_lo_source( + const std::string& src, const std::string& name, const size_t chan) = 0; /*! * Get the currently set LO source. @@ -314,7 +310,8 @@ public: * \param chan the channel index 0 to N-1 * \return the configured LO source */ - virtual const std::string get_rx_lo_source(const std::string &name, const size_t chan) = 0; + virtual const std::string get_rx_lo_source( + const std::string& name, const size_t chan) = 0; /*! * Set whether the LO used by the usrp device is exported @@ -324,14 +321,15 @@ public: * \param name the name of the LO stage to update * \param chan the channel index 0 to N-1 for the source channel */ - virtual void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan) = 0; + virtual void set_rx_lo_export_enabled( + bool enabled, const std::string& name, const size_t chan) = 0; /*! * Returns true if the currently selected LO is being exported. * \param name the name of the LO stage to query * \param chan the channel index 0 to N-1 */ - virtual bool get_rx_lo_export_enabled(const std::string &name, const size_t chan) = 0; + virtual bool get_rx_lo_export_enabled(const std::string& name, const size_t chan) = 0; /*! * Set the RX LO frequency (Advanced). @@ -340,7 +338,8 @@ public: * \param chan the channel index 0 to N-1 * \return a coerced LO frequency */ - virtual double set_rx_lo_freq(double freq, const std::string &name, const size_t chan) = 0; + virtual double set_rx_lo_freq( + double freq, const std::string& name, const size_t chan) = 0; /*! * Get the current RX LO frequency (Advanced). @@ -350,7 +349,7 @@ public: * \param chan the channel index 0 to N-1 * \return the configured LO frequency */ - virtual double get_rx_lo_freq(const std::string &name, const size_t chan) = 0; + virtual double get_rx_lo_freq(const std::string& name, const size_t chan) = 0; /*! Get a list of possible LO stage names * @@ -368,9 +367,7 @@ public: * \return a vector of strings for possible settings */ virtual std::vector<std::string> get_tx_lo_sources( - const std::string &name, - const size_t chan - ) = 0; + const std::string& name, const size_t chan) = 0; /*! * Get the LO frequency range of the tx LO. @@ -381,9 +378,7 @@ public: * \return a frequency range object */ virtual freq_range_t get_tx_lo_freq_range( - const std::string &name, - const size_t chan - ) = 0; + const std::string& name, const size_t chan) = 0; /*! * Set the LO source for a channel. @@ -395,10 +390,7 @@ public: * \param chan the channel index 0 to N-1 */ virtual void set_tx_lo_source( - const std::string &src, - const std::string &name, - const size_t chan - ) = 0; + const std::string& src, const std::string& name, const size_t chan) = 0; /*! * Get the currently set LO source. @@ -409,9 +401,7 @@ public: * \return the configured LO source */ virtual const std::string get_tx_lo_source( - const std::string &name, - const size_t chan - ) = 0; + const std::string& name, const size_t chan) = 0; /*! * Set whether the LO used by the usrp device is exported @@ -422,20 +412,14 @@ public: * \param chan the channel index 0 to N-1 for the source channel */ virtual void set_tx_lo_export_enabled( - const bool enabled, - const std::string &name, - const size_t chan - ) = 0; + const bool enabled, const std::string& name, const size_t chan) = 0; /*! * Returns true if the currently selected LO is being exported. * \param name the name of the LO stage to query * \param chan the channel index 0 to N-1 */ - virtual bool get_tx_lo_export_enabled( - const std::string &name, - const size_t chan - ) = 0; + virtual bool get_tx_lo_export_enabled(const std::string& name, const size_t chan) = 0; /*! Set the tx LO frequency (Advanced). * @@ -447,10 +431,7 @@ public: * \return a coerced LO frequency */ virtual double set_tx_lo_freq( - const double freq, - const std::string &name, - const size_t chan - ) = 0; + const double freq, const std::string& name, const size_t chan) = 0; /*! Get the current TX LO frequency (Advanced). * @@ -463,16 +444,13 @@ public: * \param chan the channel index 0 to N-1 * \return the configured LO frequency */ - virtual double get_tx_lo_freq( - const std::string &name, - const size_t chan - ) = 0; + virtual double get_tx_lo_freq(const std::string& name, const size_t chan) = 0; /************************************************************************** * Time and clock control *************************************************************************/ - /*! + /*! * Set the time source for this radio. * * May affect other radio blocks. @@ -480,7 +458,7 @@ public: * \param source A string representing the time source * \throws uhd::value_error if the value can't be applied */ - virtual void set_time_source(const std::string &source) = 0; + virtual void set_time_source(const std::string& source) = 0; /*! * Get the currently set time source. @@ -503,7 +481,7 @@ public: * * \param source a string representing the clock source */ - virtual void set_clock_source(const std::string &source) = 0; + virtual void set_clock_source(const std::string& source) = 0; /*! * Get the currently set clock source. @@ -525,11 +503,13 @@ public: * map to channels 0 and 1 respectively. A BasicRX boards has alphabetical * frontends (A, B) which map to channels differently. */ - virtual size_t get_chan_from_dboard_fe(const std::string &fe, const uhd::direction_t dir) = 0; + virtual size_t get_chan_from_dboard_fe( + const std::string& fe, const uhd::direction_t dir) = 0; /*! The inverse function to get_chan_from_dboard_fe() */ - virtual std::string get_dboard_fe_from_chan(const size_t chan, const uhd::direction_t dir) = 0; + virtual std::string get_dboard_fe_from_chan( + const size_t chan, const uhd::direction_t dir) = 0; /*! Enable or disable the setting of timestamps on Rx. */ diff --git a/host/include/uhd/rfnoc/rate_node_ctrl.hpp b/host/include/uhd/rfnoc/rate_node_ctrl.hpp index 71ebf3927..f04af11f4 100644 --- a/host/include/uhd/rfnoc/rate_node_ctrl.hpp +++ b/host/include/uhd/rfnoc/rate_node_ctrl.hpp @@ -8,11 +8,10 @@ #ifndef INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP #define INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP -#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/rfnoc/constants.hpp> +#include <uhd/rfnoc/node_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Sampling-rate-aware node control * @@ -45,12 +44,11 @@ public: * and then return that value multiplied by the decimation factor. * */ - virtual double get_input_samp_rate(size_t port=ANY_PORT); - virtual double get_output_samp_rate(size_t port=ANY_PORT); + virtual double get_input_samp_rate(size_t port = ANY_PORT); + virtual double get_output_samp_rate(size_t port = ANY_PORT); }; /* class rate_node_ctrl */ }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP */ - diff --git a/host/include/uhd/rfnoc/replay_block_ctrl.hpp b/host/include/uhd/rfnoc/replay_block_ctrl.hpp index ba49a6a7d..639d31595 100644 --- a/host/include/uhd/rfnoc/replay_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/replay_block_ctrl.hpp @@ -7,11 +7,10 @@ #ifndef INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP #define INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Replay block controller * @@ -25,23 +24,26 @@ namespace uhd { * memory, usually an off-chip DRAM. * */ -class UHD_RFNOC_API replay_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base +class UHD_RFNOC_API replay_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base { public: UHD_RFNOC_BLOCK_OBJECT(replay_block_ctrl) //! Configure the base address and size of the record buffer region (in bytes). - virtual void config_record(const uint32_t base_addr, const uint32_t size, const size_t chan) = 0; - + virtual void config_record( + const uint32_t base_addr, const uint32_t size, const size_t chan) = 0; + //! Configure the base address and size of the playback buffer region (in bytes). - virtual void config_play(const uint32_t base_addr, const uint32_t size, const size_t chan) = 0; + virtual void config_play( + const uint32_t base_addr, const uint32_t size, const size_t chan) = 0; //! Restarts recording at the beginning of the record buffer virtual void record_restart(const size_t chan) = 0; //! Returns the base address of the record buffer (in bytes). virtual uint32_t get_record_addr(const size_t chan) = 0; - + //! Returns the base address of the playback buffer (in bytes). virtual uint32_t get_play_addr(const size_t chan) = 0; @@ -50,7 +52,7 @@ public: //! Returns the current fullness of the record buffer (in bytes). virtual uint32_t get_record_fullness(const size_t chan) = 0; - + //! Returns the size of the playback buffer (in bytes). virtual uint32_t get_play_size(const size_t chan) = 0; @@ -62,7 +64,7 @@ public: //! Halts playback and clears the playback command FIFO virtual void play_halt(const size_t chan) = 0; - + }; /* class replay_block_ctrl*/ }} /* namespace uhd::rfnoc */ diff --git a/host/include/uhd/rfnoc/scalar_node_ctrl.hpp b/host/include/uhd/rfnoc/scalar_node_ctrl.hpp index e428f76fb..910a94b0c 100644 --- a/host/include/uhd/rfnoc/scalar_node_ctrl.hpp +++ b/host/include/uhd/rfnoc/scalar_node_ctrl.hpp @@ -8,11 +8,10 @@ #ifndef INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP #define INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP -#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/rfnoc/constants.hpp> +#include <uhd/rfnoc/node_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Scaling node control * @@ -45,7 +44,7 @@ public: * * \param port Port Number */ - virtual double get_input_scale_factor(size_t port=ANY_PORT); + virtual double get_input_scale_factor(size_t port = ANY_PORT); /*! Returns the scaling factor for this block on output. * @@ -54,7 +53,7 @@ public: * * \param port Port Number */ - virtual double get_output_scale_factor(size_t port=ANY_PORT); + virtual double get_output_scale_factor(size_t port = ANY_PORT); }; /* class scalar_node_ctrl */ diff --git a/host/include/uhd/rfnoc/siggen_block_ctrl.hpp b/host/include/uhd/rfnoc/siggen_block_ctrl.hpp index 3d21ca258..c58d3490d 100644 --- a/host/include/uhd/rfnoc/siggen_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/siggen_block_ctrl.hpp @@ -7,13 +7,13 @@ #ifndef INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { -class UHD_RFNOC_API siggen_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base +class UHD_RFNOC_API siggen_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base { public: UHD_RFNOC_BLOCK_OBJECT(siggen_block_ctrl) diff --git a/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp b/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp index 959148b7f..a2d4685be 100644 --- a/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp +++ b/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp @@ -11,8 +11,7 @@ #include <uhd/rfnoc/block_ctrl_base.hpp> #include <uhd/rfnoc/sink_node_ctrl.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Extends block_ctrl_base with input capabilities. * @@ -41,7 +40,7 @@ public: * \returns The stream signature for port \p block_port * \throws uhd::runtime_error if \p block_port is not a valid port */ - stream_sig_t get_input_signature(size_t block_port=0) const; + stream_sig_t get_input_signature(size_t block_port = 0) const; /*! Return a list of valid input ports. */ @@ -62,7 +61,7 @@ public: * * Returns the size of the buffer in bytes. */ - size_t get_fifo_size(size_t block_port=0) const; + size_t get_fifo_size(size_t block_port = 0) const; /*! Configure flow control for incoming streams. * @@ -77,21 +76,18 @@ public: * * \param bytes Send an ACK after this many bytes have been consumed. * Setting this to zero disables flow control acknowledgement. - * \param block_port Set up flow control for a stream coming in on this particular block port. + * \param block_port Set up flow control for a stream coming in on this particular + * block port. */ virtual void configure_flow_control_in( - const size_t bytes, - const size_t block_port=0 - ); + const size_t bytes, const size_t block_port = 0); /*! Configure the behaviour for errors on incoming packets * (e.g. sequence errors). * * */ - virtual void set_error_policy( - const std::string &policy - ); + virtual void set_error_policy(const std::string& policy); protected: /*********************************************************************** @@ -101,9 +97,7 @@ protected: * the port has an input signature. */ virtual size_t _request_input_port( - const size_t suggested_port, - const uhd::device_addr_t &args - ) const; + const size_t suggested_port, const uhd::device_addr_t& args) const; }; /* class sink_block_ctrl_base */ diff --git a/host/include/uhd/rfnoc/sink_node_ctrl.hpp b/host/include/uhd/rfnoc/sink_node_ctrl.hpp index e080035f1..22100f4c5 100644 --- a/host/include/uhd/rfnoc/sink_node_ctrl.hpp +++ b/host/include/uhd/rfnoc/sink_node_ctrl.hpp @@ -8,13 +8,12 @@ #ifndef INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP #define INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP -#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/rfnoc/constants.hpp> +#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/rfnoc/sink_node_ctrl.hpp> #include <boost/thread.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Abstract class for sink nodes. * @@ -28,8 +27,8 @@ public: * Types **********************************************************************/ typedef boost::shared_ptr<sink_node_ctrl> sptr; - typedef std::map< size_t, boost::weak_ptr<sink_node_ctrl> > node_map_t; - typedef std::pair< size_t, boost::weak_ptr<sink_node_ctrl> > node_map_pair_t; + typedef std::map<size_t, boost::weak_ptr<sink_node_ctrl> > node_map_t; + typedef std::pair<size_t, boost::weak_ptr<sink_node_ctrl> > node_map_pair_t; /*********************************************************************** * Sink block controls @@ -48,11 +47,9 @@ public: * * \returns The actual port number used. */ - size_t connect_upstream( - node_ctrl_base::sptr upstream_node, - size_t port=ANY_PORT, - const uhd::device_addr_t &args=uhd::device_addr_t() - ); + size_t connect_upstream(node_ctrl_base::sptr upstream_node, + size_t port = ANY_PORT, + const uhd::device_addr_t& args = uhd::device_addr_t()); /*! Call this function to notify a node about its streamer activity. * @@ -64,7 +61,6 @@ public: protected: - /*! Ask for a port number to connect an upstream block to. * * Typically, this will be overridden for custom behaviour. @@ -94,16 +90,15 @@ protected: * \returns A valid input port, or ANY_PORT on failure. */ virtual size_t _request_input_port( - const size_t suggested_port, - const uhd::device_addr_t &args - ) const; + const size_t suggested_port, const uhd::device_addr_t& args) const; private: /*! Makes connecting something to the input thread-safe. */ boost::mutex _input_mutex; - /*! Register a node upstream of this one (i.e., a node that can send data to this node). + /*! Register a node upstream of this one (i.e., a node that can send data to this + * node). * * By definition, the upstream node must of type source_node_ctrl. * @@ -113,10 +108,7 @@ private: * \param upstream_node A pointer to the node instantiation * \param port Port number the upstream node is connected to */ - void _register_upstream_node( - node_ctrl_base::sptr upstream_node, - size_t port - ); + void _register_upstream_node(node_ctrl_base::sptr upstream_node, size_t port); }; /* class sink_node_ctrl */ diff --git a/host/include/uhd/rfnoc/source_block_ctrl_base.hpp b/host/include/uhd/rfnoc/source_block_ctrl_base.hpp index 4f54a72c6..c0a8494c1 100644 --- a/host/include/uhd/rfnoc/source_block_ctrl_base.hpp +++ b/host/include/uhd/rfnoc/source_block_ctrl_base.hpp @@ -11,8 +11,7 @@ #include <uhd/rfnoc/block_ctrl_base.hpp> #include <uhd/rfnoc/source_node_ctrl.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Extends block_ctrl_base with receive capabilities. * @@ -22,7 +21,8 @@ namespace uhd { * data *from* this block. */ class UHD_RFNOC_API source_block_ctrl_base; -class source_block_ctrl_base : virtual public block_ctrl_base, virtual public source_node_ctrl +class source_block_ctrl_base : virtual public block_ctrl_base, + virtual public source_node_ctrl { public: typedef boost::shared_ptr<source_block_ctrl_base> sptr; @@ -50,9 +50,11 @@ public: * See also register_upstream_block(). * * \param stream_cmd The stream command. - * \param chan Channel for which this command is meant (data shall be produced on this channel). + * \param chan Channel for which this command is meant (data shall be produced on this + * channel). */ - virtual void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t chan=0); + virtual void issue_stream_cmd( + const uhd::stream_cmd_t& stream_cmd, const size_t chan = 0); /*********************************************************************** * Stream signatures @@ -67,7 +69,7 @@ public: * \returns The stream signature for port \p block_port * \throws uhd::runtime_error if \p block_port is not a valid port */ - stream_sig_t get_output_signature(size_t block_port=0) const; + stream_sig_t get_output_signature(size_t block_port = 0) const; /*! Return a list of valid output ports. */ @@ -85,10 +87,7 @@ public: * to register SR_NEXT_DST of this blocks settings bus. The value will also * have bit 16 set to 1, since some blocks require this to respect this value. */ - virtual void set_destination( - uint32_t next_address, - size_t output_block_port = 0 - ); + virtual void set_destination(uint32_t next_address, size_t output_block_port = 0); /*! Configure flow control for outgoing streams. * @@ -97,26 +96,25 @@ public: * * Override this function if your block has port-specific flow control settings. * - * \param enable_output Enable flow control module's output. If disabled, no packets will be output - * regardless of flow control state. - * \param buf_size_bytes The size of the downstream block's input FIFO size in number of bytes. Setting - * this to zero disables byte based flow control. If both byte based flow control and - * the packet limit are set to zero, the block will then produce data as fast as it can. - * \b Warning: This can cause head-of-line blocking, and potentially lock up your device! - * \param pkt_limit Limit the maximum number of packets in flight. Setting this to zero disables packet limiting. - * Usually kept disabled except for special case connections (such as DMA) that support only - * a finite number of packets in flight. + * \param enable_output Enable flow control module's output. If disabled, no packets + * will be output regardless of flow control state. \param buf_size_bytes The size of + * the downstream block's input FIFO size in number of bytes. Setting this to zero + * disables byte based flow control. If both byte based flow control and the packet + * limit are set to zero, the block will then produce data as fast as it can. \b + * Warning: This can cause head-of-line blocking, and potentially lock up your device! + * \param pkt_limit Limit the maximum number of packets in flight. Setting this to + * zero disables packet limiting. Usually kept disabled except for special case + * connections (such as DMA) that support only a finite number of packets in flight. * \param block_port Specify on which outgoing port this setting is valid. - * \param sid The SID for which this is valid. This is meant for cases where the outgoing block port is - * not sufficient to set the flow control, and as such is rarely used. + * \param sid The SID for which this is valid. This is meant for cases where the + * outgoing block port is not sufficient to set the flow control, and as such is + * rarely used. */ - virtual void configure_flow_control_out( - const bool enable_output, - const size_t buf_size_bytes, - const size_t pkt_limit=0, - const size_t block_port=0, - const uhd::sid_t &sid=uhd::sid_t() - ); + virtual void configure_flow_control_out(const bool enable_output, + const size_t buf_size_bytes, + const size_t pkt_limit = 0, + const size_t block_port = 0, + const uhd::sid_t& sid = uhd::sid_t()); protected: @@ -127,9 +125,7 @@ protected: * the port has an output signature. */ virtual size_t _request_output_port( - const size_t suggested_port, - const uhd::device_addr_t &args - ) const; + const size_t suggested_port, const uhd::device_addr_t& args) const; }; /* class source_block_ctrl_base */ diff --git a/host/include/uhd/rfnoc/source_node_ctrl.hpp b/host/include/uhd/rfnoc/source_node_ctrl.hpp index a0e8dbe9d..1dcc1ecfb 100644 --- a/host/include/uhd/rfnoc/source_node_ctrl.hpp +++ b/host/include/uhd/rfnoc/source_node_ctrl.hpp @@ -8,13 +8,12 @@ #ifndef INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP #define INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP -#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/rfnoc/constants.hpp> +#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/types/stream_cmd.hpp> #include <boost/thread.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Abstract class for source nodes. * @@ -28,8 +27,8 @@ public: * Types **********************************************************************/ typedef boost::shared_ptr<source_node_ctrl> sptr; - typedef std::map< size_t, boost::weak_ptr<source_node_ctrl> > node_map_t; - typedef std::pair< size_t, boost::weak_ptr<source_node_ctrl> > node_map_pair_t; + typedef std::map<size_t, boost::weak_ptr<source_node_ctrl> > node_map_t; + typedef std::pair<size_t, boost::weak_ptr<source_node_ctrl> > node_map_pair_t; /*********************************************************************** * Source block controls @@ -39,9 +38,7 @@ public: * \param chan Channel Index */ virtual void issue_stream_cmd( - const uhd::stream_cmd_t &stream_cmd, - const size_t chan=0 - ) = 0; + const uhd::stream_cmd_t& stream_cmd, const size_t chan = 0) = 0; /*! Connect another node downstream of this node. * @@ -57,11 +54,9 @@ public: * * \returns The actual port number used. */ - size_t connect_downstream( - node_ctrl_base::sptr downstream_node, - size_t port=ANY_PORT, - const uhd::device_addr_t &args=uhd::device_addr_t() - ); + size_t connect_downstream(node_ctrl_base::sptr downstream_node, + size_t port = ANY_PORT, + const uhd::device_addr_t& args = uhd::device_addr_t()); /*! Call this function to notify a node about its streamer activity. * @@ -72,7 +67,6 @@ public: virtual void set_rx_streamer(bool active, const size_t port); protected: - /*! Ask for a port number to connect a downstream block to. * * See sink_node_ctrl::_request_input_port(). This is the same @@ -84,9 +78,7 @@ protected: * \returns A valid input port, or ANY_PORT on failure. */ virtual size_t _request_output_port( - const size_t suggested_port, - const uhd::device_addr_t &args - ) const; + const size_t suggested_port, const uhd::device_addr_t& args) const; private: @@ -94,7 +86,8 @@ private: */ boost::mutex _output_mutex; - /*! Register a node downstream of this one (i.e., a node that receives data from this node). + /*! Register a node downstream of this one (i.e., a node that receives data from this + * node). * * By definition, the upstream node must of type sink_node_ctrl. * @@ -104,10 +97,7 @@ private: * \param downstream_node A pointer to the node instantiation * \param port Port number the downstream node is connected to */ - void _register_downstream_node( - node_ctrl_base::sptr downstream_node, - size_t port - ); + void _register_downstream_node(node_ctrl_base::sptr downstream_node, size_t port); }; /* class source_node_ctrl */ diff --git a/host/include/uhd/rfnoc/stream_sig.hpp b/host/include/uhd/rfnoc/stream_sig.hpp index 4a5128a43..3b8482781 100644 --- a/host/include/uhd/rfnoc/stream_sig.hpp +++ b/host/include/uhd/rfnoc/stream_sig.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP #define INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP -#include <iostream> #include <uhd/config.hpp> +#include <iostream> namespace uhd { namespace rfnoc { @@ -20,8 +20,9 @@ namespace uhd { namespace rfnoc { * so, some attributes may be left undefined (e.g., a FIFO block * works for any item type, so it doesn't need to set it). */ -class UHD_RFNOC_API stream_sig_t { - public: +class UHD_RFNOC_API stream_sig_t +{ +public: /*********************************************************************** * Structors ***********************************************************************/ @@ -63,11 +64,13 @@ class UHD_RFNOC_API stream_sig_t { * * \return true if streams are compatible */ - static bool is_compatible(const stream_sig_t &output_sig, const stream_sig_t &input_sig); + static bool is_compatible( + const stream_sig_t& output_sig, const stream_sig_t& input_sig); }; //! Shortcut for << stream_sig.to_string() -UHD_INLINE std::ostream& operator<< (std::ostream& out, stream_sig_t stream_sig) { +UHD_INLINE std::ostream& operator<<(std::ostream& out, stream_sig_t stream_sig) +{ out << stream_sig.to_string().c_str(); return out; } diff --git a/host/include/uhd/rfnoc/terminator_node_ctrl.hpp b/host/include/uhd/rfnoc/terminator_node_ctrl.hpp index 56ff3a3c1..5909a6367 100644 --- a/host/include/uhd/rfnoc/terminator_node_ctrl.hpp +++ b/host/include/uhd/rfnoc/terminator_node_ctrl.hpp @@ -10,8 +10,7 @@ #include <uhd/rfnoc/node_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Abstract class for terminator nodes (i.e. nodes that terminate * the flow graph). diff --git a/host/include/uhd/rfnoc/tick_node_ctrl.hpp b/host/include/uhd/rfnoc/tick_node_ctrl.hpp index 0b288274f..da75a209f 100644 --- a/host/include/uhd/rfnoc/tick_node_ctrl.hpp +++ b/host/include/uhd/rfnoc/tick_node_ctrl.hpp @@ -8,11 +8,10 @@ #ifndef INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP #define INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP -#include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/rfnoc/constants.hpp> +#include <uhd/rfnoc/node_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Tick-rate-aware node control * @@ -45,12 +44,14 @@ public: * or it's a tick rate defined by an adjacent block. * In that case, performs a graph search to figure out the tick rate. */ - double get_tick_rate( - const std::set< node_ctrl_base::sptr > &_explored_nodes=std::set< node_ctrl_base::sptr >() - ); + double get_tick_rate(const std::set<node_ctrl_base::sptr>& _explored_nodes = + std::set<node_ctrl_base::sptr>()); protected: - virtual double _get_tick_rate() { return RATE_UNDEFINED; }; + virtual double _get_tick_rate() + { + return RATE_UNDEFINED; + }; }; /* class tick_node_ctrl */ diff --git a/host/include/uhd/rfnoc/traffic_counter.hpp b/host/include/uhd/rfnoc/traffic_counter.hpp index bff04e38e..9a0546f17 100644 --- a/host/include/uhd/rfnoc/traffic_counter.hpp +++ b/host/include/uhd/rfnoc/traffic_counter.hpp @@ -9,47 +9,42 @@ #include <uhd/property_tree.hpp> #include <stdint.h> -#include <memory> -#include <functional> #include <type_traits> +#include <functional> +#include <memory> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { class traffic_counter { public: typedef std::shared_ptr<traffic_counter> sptr; - typedef std::function<void(const uint32_t addr, const uint32_t data)> write_reg_fn_t ; - typedef std::function<uint64_t(const uint32_t addr)> read_reg_fn_t ; + typedef std::function<void(const uint32_t addr, const uint32_t data)> write_reg_fn_t; + typedef std::function<uint64_t(const uint32_t addr)> read_reg_fn_t; - traffic_counter( - uhd::property_tree::sptr tree, + traffic_counter(uhd::property_tree::sptr tree, uhd::fs_path root_path, write_reg_fn_t write_reg_fn, - read_reg_fn_t read_reg_fn - ) : - _write_reg_fn(write_reg_fn), - _read_reg_fn(read_reg_fn) + read_reg_fn_t read_reg_fn) + : _write_reg_fn(write_reg_fn), _read_reg_fn(read_reg_fn) { - const uint32_t id_reg_offset = 0; + const uint32_t id_reg_offset = 0; const uint32_t first_counter_offset = 1; - const uint64_t traffic_counter_id = 0x712AFF1C00000000ULL; + const uint64_t traffic_counter_id = 0x712AFF1C00000000ULL; // Check traffic counter id to determine if it's present const uint64_t id = _read_reg_fn(id_reg_offset); // If present, add properties - if (id == traffic_counter_id) - { - tree->create<bool>(root_path/"traffic_counter/enable") + if (id == traffic_counter_id) { + tree->create<bool>(root_path / "traffic_counter/enable") .add_coerced_subscriber([this](const bool enable) { - uint32_t val = enable? 1 : 0; + uint32_t val = enable ? 1 : 0; return _write_reg_fn(0, val); - }).set(false); + }) + .set(false); - const char* counters[] = { - "bus_clock_ticks", + const char* counters[] = {"bus_clock_ticks", "xbar_to_shell_xfer_count", "xbar_to_shell_pkt_count", "shell_to_xbar_xfer_count", @@ -60,16 +55,17 @@ public: "ce_to_shell_pkt_count"}; for (size_t i = 0; i < std::extent<decltype(counters)>::value; i++) { - tree->create<uint64_t>(root_path/"traffic_counter"/counters[i]) + tree->create<uint64_t>(root_path / "traffic_counter" / counters[i]) .set_publisher([this, i, first_counter_offset]() { - return _read_reg_fn(i+first_counter_offset); + return _read_reg_fn(i + first_counter_offset); }); } } } + private: write_reg_fn_t _write_reg_fn; - read_reg_fn_t _read_reg_fn; + read_reg_fn_t _read_reg_fn; }; }} /* namespace uhd::rfnoc */ diff --git a/host/include/uhd/rfnoc/window_block_ctrl.hpp b/host/include/uhd/rfnoc/window_block_ctrl.hpp index 093b34e67..ee5439b40 100644 --- a/host/include/uhd/rfnoc/window_block_ctrl.hpp +++ b/host/include/uhd/rfnoc/window_block_ctrl.hpp @@ -7,11 +7,10 @@ #ifndef INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP #define INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP -#include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Block controller for the standard windowing RFNoC block. * @@ -24,22 +23,23 @@ namespace uhd { * It will perform one window operation per incoming packet, treating it * as a vector of samples. */ -class UHD_RFNOC_API window_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base +class UHD_RFNOC_API window_block_ctrl : public source_block_ctrl_base, + public sink_block_ctrl_base { public: UHD_RFNOC_BLOCK_OBJECT(window_block_ctrl) - static const size_t MAX_COEFF_VAL = 32767; - static const uint32_t SR_WINDOW_LEN = 131; // Note: AXI config bus uses 129 & 130 - static const uint32_t RB_MAX_WINDOW_LEN = 0; - static const uint32_t AXIS_WINDOW_LOAD = AXIS_CONFIG_BUS+0; // 2*0+0 - static const uint32_t AXIS_WINDOW_LOAD_TLAST = AXIS_CONFIG_BUS+1; // 2*0+1 + static const size_t MAX_COEFF_VAL = 32767; + static const uint32_t SR_WINDOW_LEN = 131; // Note: AXI config bus uses 129 & 130 + static const uint32_t RB_MAX_WINDOW_LEN = 0; + static const uint32_t AXIS_WINDOW_LOAD = AXIS_CONFIG_BUS + 0; // 2*0+0 + static const uint32_t AXIS_WINDOW_LOAD_TLAST = AXIS_CONFIG_BUS + 1; // 2*0+1 //! Configure the window coefficients // // \p coeffs size determines the window length. If it longer than // the maximum window length, throws a uhd::value_error. - virtual void set_window(const std::vector<int> &coeffs) = 0; + virtual void set_window(const std::vector<int>& coeffs) = 0; //! Returns the maximum window length. virtual size_t get_max_len() const = 0; diff --git a/host/include/uhd/stream.hpp b/host/include/uhd/stream.hpp index 757198dde..133893cf9 100644 --- a/host/include/uhd/stream.hpp +++ b/host/include/uhd/stream.hpp @@ -9,16 +9,16 @@ #define INCLUDED_UHD_STREAM_HPP #include <uhd/config.hpp> -#include <uhd/types/metadata.hpp> #include <uhd/types/device_addr.hpp> -#include <uhd/types/stream_cmd.hpp> +#include <uhd/types/metadata.hpp> #include <uhd/types/ref_vector.hpp> -#include <boost/utility.hpp> +#include <uhd/types/stream_cmd.hpp> #include <boost/shared_ptr.hpp> -#include <vector> +#include <boost/utility.hpp> #include <string> +#include <vector> -namespace uhd{ +namespace uhd { /*! * A struct of parameters to construct a streamer. @@ -55,13 +55,11 @@ namespace uhd{ * stream_args.args["block_port2"] = "1"; * \endcode */ -struct UHD_API stream_args_t{ - +struct UHD_API stream_args_t +{ //! Convenience constructor for streamer args - stream_args_t( - const std::string &cpu = "", - const std::string &otw = "" - ){ + stream_args_t(const std::string& cpu = "", const std::string& otw = "") + { cpu_format = cpu; otw_format = otw; } @@ -95,12 +93,12 @@ struct UHD_API stream_args_t{ * - s16 - R16_1 R16_0 * - s8 - R8_3 R8_2 R8_1 R8_0 * - * Setting the OTW ("over-the-wire") format is, in theory, transparent to the application, - * but changing this can have some side effects. Using less bits for example (e.g. when going - * from `otw_format` `sc16` to `sc8`) will reduce the dynamic range, and increases quantization - * noise. On the other hand, it reduces the load on the data link and thus allows more bandwidth - * (a USRP N210 can work with 25 MHz bandwidth for 16-Bit complex samples, and 50 MHz for 8-Bit - * complex samples). + * Setting the OTW ("over-the-wire") format is, in theory, transparent to the + * application, but changing this can have some side effects. Using less bits for + * example (e.g. when going from `otw_format` `sc16` to `sc8`) will reduce the dynamic + * range, and increases quantization noise. On the other hand, it reduces the load on + * the data link and thus allows more bandwidth (a USRP N210 can work with 25 MHz + * bandwidth for 16-Bit complex samples, and 50 MHz for 8-Bit complex samples). */ std::string otw_format; @@ -113,16 +111,17 @@ struct UHD_API stream_args_t{ * Set the "fullscale" to scale the samples in the host to the * expected input range and/or output range of your application. * - * - peak: specifies a fractional sample level to calculate scaling with the sc8 wire format. - * When using sc8 samples over the wire, the device must scale samples - * (both on the host and in the device) to satisfy the dynamic range needs. - * The peak value specifies a fraction of the maximum sample level (1.0 = 100%). - * Set peak to max_sample_level/full_scale_level to ensure optimum dynamic range. + * - peak: specifies a fractional sample level to calculate scaling with the sc8 wire + * format. When using sc8 samples over the wire, the device must scale samples (both + * on the host and in the device) to satisfy the dynamic range needs. The peak value + * specifies a fraction of the maximum sample level (1.0 = 100%). Set peak to + * max_sample_level/full_scale_level to ensure optimum dynamic range. * * - underflow_policy: how the TX DSP should recover from underflow. * Possible options are "next_burst" or "next_packet". - * In the "next_burst" mode, the DSP drops incoming packets until a new burst is started. - * In the "next_packet" mode, the DSP starts transmitting again at the next packet. + * In the "next_burst" mode, the DSP drops incoming packets until a new burst is + * started. In the "next_packet" mode, the DSP starts transmitting again at the next + * packet. * * - spp: (samples per packet) controls the size of RX packets. * When not specified, the packets are always maximum frame size. @@ -150,9 +149,9 @@ struct UHD_API stream_args_t{ * of `A:0 B:0`. This means the device has two channels available. * * Setting `stream_args.channels = (0, 1)` therefore configures MIMO streaming - * from both channels. By switching the channel indexes, `stream_args.channels = (1, 0)`, - * the channels are switched and the first channel of the USRP is mapped to - * the second channel in the application. + * from both channels. By switching the channel indexes, `stream_args.channels = (1, + * 0)`, the channels are switched and the first channel of the USRP is mapped to the + * second channel in the application. * * If only a single channel is used for streaming, `stream_args.channels = (1,)` would * only select a single channel (in this case, the second one). When streaming @@ -167,7 +166,8 @@ struct UHD_API stream_args_t{ * It represents the layer between the samples on the host * and samples inside the device's receive DSP processing. */ -class UHD_API rx_streamer : boost::noncopyable{ +class UHD_API rx_streamer : boost::noncopyable +{ public: typedef boost::shared_ptr<rx_streamer> sptr; @@ -180,7 +180,7 @@ public: virtual size_t get_max_num_samps(void) const = 0; //! Typedef for a pointer to a single, or a collection of recv buffers - typedef ref_vector<void *> buffs_type; + typedef ref_vector<void*> buffs_type; /*! * Receive buffers containing samples described by the metadata. @@ -216,13 +216,11 @@ public: * \param one_packet return after the first packet is received * \return the number of samples received or 0 on error */ - virtual size_t recv( - const buffs_type &buffs, + virtual size_t recv(const buffs_type& buffs, const size_t nsamps_per_buff, - rx_metadata_t &metadata, - const double timeout = 0.1, - const bool one_packet = false - ) = 0; + rx_metadata_t& metadata, + const double timeout = 0.1, + const bool one_packet = false) = 0; /*! * Issue a stream command to the usrp device. @@ -235,7 +233,7 @@ public: * * \param stream_cmd the stream command to issue */ - virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; + virtual void issue_stream_cmd(const stream_cmd_t& stream_cmd) = 0; }; /*! @@ -243,7 +241,8 @@ public: * It represents the layer between the samples on the host * and samples inside the device's transmit DSP processing. */ -class UHD_API tx_streamer : boost::noncopyable{ +class UHD_API tx_streamer : boost::noncopyable +{ public: typedef boost::shared_ptr<tx_streamer> sptr; @@ -256,7 +255,7 @@ public: virtual size_t get_max_num_samps(void) const = 0; //! Typedef for a pointer to a single, or a collection of send buffers - typedef ref_vector<const void *> buffs_type; + typedef ref_vector<const void*> buffs_type; /*! * Send buffers containing samples described by the metadata. @@ -279,12 +278,10 @@ public: * \param timeout the timeout in seconds to wait on a packet * \return the number of samples sent */ - virtual size_t send( - const buffs_type &buffs, + virtual size_t send(const buffs_type& buffs, const size_t nsamps_per_buff, - const tx_metadata_t &metadata, - const double timeout = 0.1 - ) = 0; + const tx_metadata_t& metadata, + const double timeout = 0.1) = 0; /*! * Receive and asynchronous message from this TX stream. @@ -293,10 +290,9 @@ public: * \return true when the async_metadata is valid, false for timeout */ virtual bool recv_async_msg( - async_metadata_t &async_metadata, double timeout = 0.1 - ) = 0; + async_metadata_t& async_metadata, double timeout = 0.1) = 0; }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_STREAM_HPP */ diff --git a/host/include/uhd/transport/bounded_buffer.hpp b/host/include/uhd/transport/bounded_buffer.hpp index 76966ed2d..354cff5e2 100644 --- a/host/include/uhd/transport/bounded_buffer.hpp +++ b/host/include/uhd/transport/bounded_buffer.hpp @@ -10,102 +10,109 @@ #include <uhd/transport/bounded_buffer.ipp> //detail -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { +/*! + * Implement a templated bounded buffer: + * Used for passing elements between threads in a producer-consumer model. + * The bounded buffer implemented waits and timed waits with condition variables. + * The pop operation blocks on the bounded_buffer to become non empty. + * The push operation blocks on the bounded_buffer to become non full. + */ +template <typename elem_type> class bounded_buffer +{ +public: /*! - * Implement a templated bounded buffer: - * Used for passing elements between threads in a producer-consumer model. - * The bounded buffer implemented waits and timed waits with condition variables. - * The pop operation blocks on the bounded_buffer to become non empty. - * The push operation blocks on the bounded_buffer to become non full. + * Create a new bounded buffer object. + * \param capacity the bounded_buffer capacity */ - template <typename elem_type> class bounded_buffer{ - public: + bounded_buffer(size_t capacity) : _detail(capacity) + { + /* NOP */ + } - /*! - * Create a new bounded buffer object. - * \param capacity the bounded_buffer capacity - */ - bounded_buffer(size_t capacity): - _detail(capacity) - { - /* NOP */ - } - - /*! - * Push a new element into the bounded buffer immediately. - * The element will not be pushed when the buffer is full. - * \param elem the element reference pop to - * \return false when the buffer is full - */ - UHD_INLINE bool push_with_haste(const elem_type &elem){ - return _detail.push_with_haste(elem); - } + /*! + * Push a new element into the bounded buffer immediately. + * The element will not be pushed when the buffer is full. + * \param elem the element reference pop to + * \return false when the buffer is full + */ + UHD_INLINE bool push_with_haste(const elem_type& elem) + { + return _detail.push_with_haste(elem); + } - /*! - * Push a new element into the bounded buffer. - * If the buffer is full prior to the push, - * make room by popping the oldest element. - * \param elem the new element to push - * \return true if the element fit without popping for space - */ - UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){ - return _detail.push_with_pop_on_full(elem); - } + /*! + * Push a new element into the bounded buffer. + * If the buffer is full prior to the push, + * make room by popping the oldest element. + * \param elem the new element to push + * \return true if the element fit without popping for space + */ + UHD_INLINE bool push_with_pop_on_full(const elem_type& elem) + { + return _detail.push_with_pop_on_full(elem); + } - /*! - * Push a new element into the bounded_buffer. - * Wait until the bounded_buffer becomes non-full. - * \param elem the new element to push - */ - UHD_INLINE void push_with_wait(const elem_type &elem){ - return _detail.push_with_wait(elem); - } + /*! + * Push a new element into the bounded_buffer. + * Wait until the bounded_buffer becomes non-full. + * \param elem the new element to push + */ + UHD_INLINE void push_with_wait(const elem_type& elem) + { + return _detail.push_with_wait(elem); + } - /*! - * Push a new element into the bounded_buffer. - * Wait until the bounded_buffer becomes non-full or timeout. - * \param elem the new element to push - * \param timeout the timeout in seconds - * \return false when the operation times out - */ - UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout){ - return _detail.push_with_timed_wait(elem, timeout); - } + /*! + * Push a new element into the bounded_buffer. + * Wait until the bounded_buffer becomes non-full or timeout. + * \param elem the new element to push + * \param timeout the timeout in seconds + * \return false when the operation times out + */ + UHD_INLINE bool push_with_timed_wait(const elem_type& elem, double timeout) + { + return _detail.push_with_timed_wait(elem, timeout); + } - /*! - * Pop an element from the bounded buffer immediately. - * The element will not be popped when the buffer is empty. - * \param elem the element reference pop to - * \return false when the buffer is empty - */ - UHD_INLINE bool pop_with_haste(elem_type &elem){ - return _detail.pop_with_haste(elem); - } + /*! + * Pop an element from the bounded buffer immediately. + * The element will not be popped when the buffer is empty. + * \param elem the element reference pop to + * \return false when the buffer is empty + */ + UHD_INLINE bool pop_with_haste(elem_type& elem) + { + return _detail.pop_with_haste(elem); + } - /*! - * Pop an element from the bounded_buffer. - * Wait until the bounded_buffer becomes non-empty. - * \param elem the element reference pop to - */ - UHD_INLINE void pop_with_wait(elem_type &elem){ - return _detail.pop_with_wait(elem); - } + /*! + * Pop an element from the bounded_buffer. + * Wait until the bounded_buffer becomes non-empty. + * \param elem the element reference pop to + */ + UHD_INLINE void pop_with_wait(elem_type& elem) + { + return _detail.pop_with_wait(elem); + } - /*! - * Pop an element from the bounded_buffer. - * Wait until the bounded_buffer becomes non-empty or timeout. - * \param elem the element reference pop to - * \param timeout the timeout in seconds - * \return false when the operation times out - */ - UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout){ - return _detail.pop_with_timed_wait(elem, timeout); - } + /*! + * Pop an element from the bounded_buffer. + * Wait until the bounded_buffer becomes non-empty or timeout. + * \param elem the element reference pop to + * \param timeout the timeout in seconds + * \return false when the operation times out + */ + UHD_INLINE bool pop_with_timed_wait(elem_type& elem, double timeout) + { + return _detail.pop_with_timed_wait(elem, timeout); + } - private: bounded_buffer_detail<elem_type> _detail; - }; +private: + bounded_buffer_detail<elem_type> _detail; +}; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP */ diff --git a/host/include/uhd/transport/buffer_pool.hpp b/host/include/uhd/transport/buffer_pool.hpp index 0ad835c1b..769c78180 100644 --- a/host/include/uhd/transport/buffer_pool.hpp +++ b/host/include/uhd/transport/buffer_pool.hpp @@ -9,43 +9,41 @@ #define INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP #include <uhd/config.hpp> -#include <boost/utility.hpp> #include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> + +namespace uhd { namespace transport { + +/*! + * A buffer pool manages memory for a homogeneous set of buffers. + * Each buffer is the pool start at a 16-byte alignment boundary. + */ +class UHD_API buffer_pool : boost::noncopyable +{ +public: + typedef boost::shared_ptr<buffer_pool> sptr; + typedef void* ptr_type; -namespace uhd{ namespace transport{ + virtual ~buffer_pool(void) = 0; /*! - * A buffer pool manages memory for a homogeneous set of buffers. - * Each buffer is the pool start at a 16-byte alignment boundary. + * Make a new buffer pool. + * \param num_buffs the number of buffers to allocate + * \param buff_size the size of each buffer in bytes + * \param alignment the alignment boundary in bytes + * \return a new buffer pool buff_size X num_buffs */ - class UHD_API buffer_pool : boost::noncopyable{ - public: - typedef boost::shared_ptr<buffer_pool> sptr; - typedef void * ptr_type; - - virtual ~buffer_pool(void) = 0; - - /*! - * Make a new buffer pool. - * \param num_buffs the number of buffers to allocate - * \param buff_size the size of each buffer in bytes - * \param alignment the alignment boundary in bytes - * \return a new buffer pool buff_size X num_buffs - */ - static sptr make( - const size_t num_buffs, - const size_t buff_size, - const size_t alignment = 16 - ); - - //! Get a pointer to the buffer start at the specified index - virtual ptr_type at(const size_t index) const = 0; - - //! Get the number of buffers in this pool - virtual size_t size(void) const = 0; - }; - -}} //namespace + static sptr make( + const size_t num_buffs, const size_t buff_size, const size_t alignment = 16); + + //! Get a pointer to the buffer start at the specified index + virtual ptr_type at(const size_t index) const = 0; + + //! Get the number of buffers in this pool + virtual size_t size(void) const = 0; +}; + +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP */ diff --git a/host/include/uhd/transport/chdr.hpp b/host/include/uhd/transport/chdr.hpp index 64260fbfc..f4b5c91f1 100644 --- a/host/include/uhd/transport/chdr.hpp +++ b/host/include/uhd/transport/chdr.hpp @@ -10,7 +10,7 @@ #include <uhd/transport/vrt_if_packet.hpp> -namespace uhd{ namespace transport{ namespace vrt{ +namespace uhd { namespace transport { namespace vrt { /*! \brief CHDR related function * @@ -34,70 +34,59 @@ namespace uhd{ namespace transport{ namespace vrt{ * * In the unpacker, these values will be set accordingly. */ -namespace chdr{ +namespace chdr { - //! The maximum number of 64-bit words in a CHDR header - static const size_t max_if_hdr_words64 = 2; // CHDR + tsf (fractional timestamp) +//! The maximum number of 64-bit words in a CHDR header +static const size_t max_if_hdr_words64 = 2; // CHDR + tsf (fractional timestamp) - /*! - * Pack a CHDR header from metadata (big endian format). - * - * See \ref vrt_pack_contract, but `link_type` is assumed to be - * `LINK_TYPE_CHDR`. - * - * \param packet_buff memory to write the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_pack_be( - uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); +/*! + * Pack a CHDR header from metadata (big endian format). + * + * See \ref vrt_pack_contract, but `link_type` is assumed to be + * `LINK_TYPE_CHDR`. + * + * \param packet_buff memory to write the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_pack_be(uint32_t* packet_buff, if_packet_info_t& if_packet_info); - /*! - * Unpack a CHDR header to metadata (big endian format). - * - * See \ref vrt_unpack_contract, but `link_type` is assumed to be - * `LINK_TYPE_CHDR`. - * - * \param packet_buff memory to read the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_unpack_be( - const uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); +/*! + * Unpack a CHDR header to metadata (big endian format). + * + * See \ref vrt_unpack_contract, but `link_type` is assumed to be + * `LINK_TYPE_CHDR`. + * + * \param packet_buff memory to read the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_unpack_be( + const uint32_t* packet_buff, if_packet_info_t& if_packet_info); - /*! - * Pack a CHDR header from metadata (little endian format). - * - * See \ref vrt_pack_contract, but `link_type` is assumed to be - * `LINK_TYPE_CHDR`. - * - * \param packet_buff memory to write the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_pack_le( - uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); +/*! + * Pack a CHDR header from metadata (little endian format). + * + * See \ref vrt_pack_contract, but `link_type` is assumed to be + * `LINK_TYPE_CHDR`. + * + * \param packet_buff memory to write the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_pack_le(uint32_t* packet_buff, if_packet_info_t& if_packet_info); - /*! - * Unpack a CHDR header to metadata (little endian format). - * - * See \ref vrt_unpack_contract, but `link_type` is assumed to be - * `LINK_TYPE_CHDR`. - * - * \param packet_buff memory to read the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_unpack_le( - const uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); +/*! + * Unpack a CHDR header to metadata (little endian format). + * + * See \ref vrt_unpack_contract, but `link_type` is assumed to be + * `LINK_TYPE_CHDR`. + * + * \param packet_buff memory to read the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_unpack_le( + const uint32_t* packet_buff, if_packet_info_t& if_packet_info); -} //namespace chdr +} // namespace chdr -}}} //namespace uhd::transport::vrt +}}} // namespace uhd::transport::vrt #endif /* INCLUDED_UHD_TRANSPORT_CHDR_HPP */ - diff --git a/host/include/uhd/transport/if_addrs.hpp b/host/include/uhd/transport/if_addrs.hpp index 0458fe4f7..b97c6156e 100644 --- a/host/include/uhd/transport/if_addrs.hpp +++ b/host/include/uhd/transport/if_addrs.hpp @@ -12,25 +12,26 @@ #include <string> #include <vector> -namespace uhd{ namespace transport{ - - /*! - * The address for a network interface. - */ - struct UHD_API if_addrs_t{ - std::string inet; - std::string mask; - std::string bcast; - }; - - /*! - * Get a list of network interface addresses. - * The internal implementation is system-dependent. - * \return a vector of if addrs - */ - UHD_API std::vector<if_addrs_t> get_if_addrs(void); - -}} //namespace +namespace uhd { namespace transport { + +/*! + * The address for a network interface. + */ +struct UHD_API if_addrs_t +{ + std::string inet; + std::string mask; + std::string bcast; +}; + +/*! + * Get a list of network interface addresses. + * The internal implementation is system-dependent. + * \return a vector of if addrs + */ +UHD_API std::vector<if_addrs_t> get_if_addrs(void); + +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP */ diff --git a/host/include/uhd/transport/muxed_zero_copy_if.hpp b/host/include/uhd/transport/muxed_zero_copy_if.hpp index 0cf293a18..f69e6f288 100644 --- a/host/include/uhd/transport/muxed_zero_copy_if.hpp +++ b/host/include/uhd/transport/muxed_zero_copy_if.hpp @@ -8,11 +8,11 @@ #ifndef INCLUDED_LIBUHD_TRANSPORT_MUXED_ZERO_COPY_IF_HPP #define INCLUDED_LIBUHD_TRANSPORT_MUXED_ZERO_COPY_IF_HPP -#include <uhd/transport/zero_copy.hpp> #include <uhd/config.hpp> +#include <uhd/transport/zero_copy.hpp> +#include <stdint.h> #include <boost/function.hpp> #include <boost/noncopyable.hpp> -#include <stdint.h> namespace uhd { namespace transport { @@ -25,7 +25,8 @@ namespace uhd { namespace transport { * appropriate virtual streams with the given classifier * function. A worker therad is spawned to handle the demuxing. */ -class muxed_zero_copy_if : private boost::noncopyable { +class muxed_zero_copy_if : private boost::noncopyable +{ public: typedef boost::shared_ptr<muxed_zero_copy_if> sptr; @@ -54,9 +55,11 @@ public: virtual size_t get_num_dropped_frames() const = 0; //! Make a new demuxer from a transport and parameters - static sptr make(zero_copy_if::sptr base_xport, stream_classifier_fn classify_fn, size_t max_streams); + static sptr make(zero_copy_if::sptr base_xport, + stream_classifier_fn classify_fn, + size_t max_streams); }; -}} //namespace uhd::transport +}} // namespace uhd::transport #endif /* INCLUDED_LIBUHD_TRANSPORT_MUXED_ZERO_COPY_IF_HPP */ diff --git a/host/include/uhd/transport/nirio/rpc/rpc_client.hpp b/host/include/uhd/transport/nirio/rpc/rpc_client.hpp index bf309ad28..536210c31 100644 --- a/host/include/uhd/transport/nirio/rpc/rpc_client.hpp +++ b/host/include/uhd/transport/nirio/rpc/rpc_client.hpp @@ -8,52 +8,54 @@ #ifndef INCLUDED_RPC_CLIENT_HPP #define INCLUDED_RPC_CLIENT_HPP +#include "rpc_common.hpp" +#include <uhd/utils/log.hpp> #include <boost/asio.hpp> #include <boost/smart_ptr.hpp> -#include <boost/thread/thread.hpp> #include <boost/thread/condition_variable.hpp> -#include "rpc_common.hpp" -#include <uhd/utils/log.hpp> +#include <boost/thread/thread.hpp> namespace uhd { namespace usrprio_rpc { class rpc_client : private boost::noncopyable { public: - static const uint32_t CURRENT_VERSION = 1; + static const uint32_t CURRENT_VERSION = 1; static const uint32_t OLDEST_COMPATIBLE_VERSION = 1; - rpc_client( - const std::string& server, + rpc_client(const std::string& server, const std::string& port, uint32_t process_id, uint32_t host_id); ~rpc_client(); - const boost::system::error_code& call( - func_id_t func_id, + const boost::system::error_code& call(func_id_t func_id, const func_args_writer_t& in_args, - func_args_reader_t &out_args, + func_args_reader_t& out_args, boost::posix_time::milliseconds timeout); - inline const boost::system::error_code& status() const { + inline const boost::system::error_code& status() const + { return _exec_err; } /* [Possible boost::system::error_code values] * boost::asio::error::connection_aborted: Network connection failure * boost::asio::error::eof: Network connection closed cleanly - * boost::asio::error::connection_refused: Software handshake failure (version mismatch, etc) - * boost::asio::error::timed_out: RPC call timed out + * boost::asio::error::connection_refused: Software handshake failure (version + * mismatch, etc) boost::asio::error::timed_out: RPC call timed out * boost::asio::error::operation_aborted: RPC call aborted but connection alive */ private: - void _handle_response_hdr(const boost::system::error_code& err, size_t transferred, size_t expected); - void _handle_response_data(const boost::system::error_code& err, size_t transferred, size_t expected); + void _handle_response_hdr( + const boost::system::error_code& err, size_t transferred, size_t expected); + void _handle_response_data( + const boost::system::error_code& err, size_t transferred, size_t expected); void _wait_for_next_response_header(); - inline void _stop_io_service() { + inline void _stop_io_service() + { if (_io_service_thread.get()) { UHD_LOGGER_INFO("NIRIO") << "rpc_client stopping..."; _io_service.stop(); @@ -63,22 +65,22 @@ private: } } - //Services - boost::asio::io_service _io_service; - boost::scoped_ptr<boost::thread> _io_service_thread; - boost::asio::ip::tcp::socket _socket; - //Handshake info - hshake_args_t _hshake_args_client; - hshake_args_t _hshake_args_server; - //In-out function args - func_xport_buf_t _request; - func_xport_buf_t _response; - //Synchronization - boost::mutex _mutex; - boost::condition_variable _exec_gate; - boost::system::error_code _exec_err; + // Services + boost::asio::io_service _io_service; + boost::scoped_ptr<boost::thread> _io_service_thread; + boost::asio::ip::tcp::socket _socket; + // Handshake info + hshake_args_t _hshake_args_client; + hshake_args_t _hshake_args_server; + // In-out function args + func_xport_buf_t _request; + func_xport_buf_t _response; + // Synchronization + boost::mutex _mutex; + boost::condition_variable _exec_gate; + boost::system::error_code _exec_err; }; -}} +}} // namespace uhd::usrprio_rpc #endif /* INCLUDED_RPC_CLIENT_HPP */ diff --git a/host/include/uhd/transport/nirio/rpc/rpc_common.hpp b/host/include/uhd/transport/nirio/rpc/rpc_common.hpp index c1261f634..2384c0f61 100644 --- a/host/include/uhd/transport/nirio/rpc/rpc_common.hpp +++ b/host/include/uhd/transport/nirio/rpc/rpc_common.hpp @@ -10,139 +10,150 @@ #define USE_BINARY_ARCHIVE 0 -#include <string> #include <iostream> #include <sstream> +#include <string> #include <vector> #if (USE_BINARY_ARCHIVE) - #include <boost/archive/binary_oarchive.hpp> - #include <boost/archive/binary_iarchive.hpp> +# include <boost/archive/binary_iarchive.hpp> +# include <boost/archive/binary_oarchive.hpp> #else - #include <boost/archive/text_oarchive.hpp> - #include <boost/archive/text_iarchive.hpp> +# include <boost/archive/text_iarchive.hpp> +# include <boost/archive/text_oarchive.hpp> #endif #include <stdint.h> namespace uhd { namespace usrprio_rpc { //[Over-the-wire] IDs -typedef int32_t func_id_t; +typedef int32_t func_id_t; typedef uint64_t client_id_t; #define build_client_id(host_id, process_id) \ ((static_cast<uint64_t>(host_id) << 32) | static_cast<uint64_t>(process_id)) -#define get_process_id_from_client_id(client_id) \ - (static_cast<int32_t>(client_id)) -#define get_host_id_from_client_id(client_id) \ - (static_cast<uint32_t>(client_id >> 32)) +#define get_process_id_from_client_id(client_id) (static_cast<int32_t>(client_id)) +#define get_host_id_from_client_id(client_id) (static_cast<uint32_t>(client_id >> 32)) //[Over-the-wire] Handshake format -struct hshake_args_t { +struct hshake_args_t +{ uint32_t version; uint32_t oldest_comp_version; - int32_t boost_archive_version; - client_id_t client_id; + int32_t boost_archive_version; + client_id_t client_id; }; //[Over-the-wire] Header for RPC request and response -class func_args_header_t { +class func_args_header_t +{ public: - func_id_t func_id; - client_id_t client_id; + func_id_t func_id; + client_id_t client_id; uint32_t func_args_size; - static bool match_function(const func_args_header_t& a, const func_args_header_t& b) { + static bool match_function(const func_args_header_t& a, const func_args_header_t& b) + { return ((a.func_id == b.func_id) && (a.client_id == b.client_id)); } }; //[Internal] Storage for RPC header and arguments -class func_xport_buf_t { +class func_xport_buf_t +{ public: - func_args_header_t header; - std::vector<char> data; + func_args_header_t header; + std::vector<char> data; }; //[Internal] Serializer for RPC input parameters -class func_args_writer_t { +class func_args_writer_t +{ public: func_args_writer_t() : _stream(), _archive(_stream, boost::archive::no_header) {} - template<typename data_t> - void push(const data_t& d) { + template <typename data_t> void push(const data_t& d) + { _archive << d; } - template<typename data_t> - func_args_writer_t& operator<< (const data_t& data) { + template <typename data_t> func_args_writer_t& operator<<(const data_t& data) + { push(data); return *this; } - void store(std::vector<char>& data) const { + void store(std::vector<char>& data) const + { const std::string& str = _stream.str(); data.resize(str.length()); data.assign((char*)str.c_str(), ((char*)str.c_str()) + str.length()); } private: - std::ostringstream _stream; + std::ostringstream _stream; #if (USE_BINARY_ARCHIVE) boost::archive::binary_oarchive _archive; #else - boost::archive::text_oarchive _archive; + boost::archive::text_oarchive _archive; #endif }; //[Internal] Deserializer for RPC output parameters -class func_args_reader_t { +class func_args_reader_t +{ public: func_args_reader_t() : _stream(), _archive() {} - template<typename data_t> - void pull(data_t& d) const { - if (_archive) (*_archive) >> d; + template <typename data_t> void pull(data_t& d) const + { + if (_archive) + (*_archive) >> d; } - template<typename data_t> - const func_args_reader_t& operator>> (data_t& data) const { + template <typename data_t> const func_args_reader_t& operator>>(data_t& data) const + { pull(data); return *this; } - void load(const std::vector<char>& data) { + void load(const std::vector<char>& data) + { _stream.str(std::string(data.begin(), data.end())); #if (USE_BINARY_ARCHIVE) - _archive.reset(new boost::archive::binary_iarchive(_stream, boost::archive::no_header)); + _archive.reset( + new boost::archive::binary_iarchive(_stream, boost::archive::no_header)); #else - _archive.reset(new boost::archive::text_iarchive(_stream, boost::archive::no_header)); + _archive.reset( + new boost::archive::text_iarchive(_stream, boost::archive::no_header)); #endif } private: - std::istringstream _stream; + std::istringstream _stream; #if (USE_BINARY_ARCHIVE) - boost::scoped_ptr<boost::archive::binary_iarchive> _archive; + boost::scoped_ptr<boost::archive::binary_iarchive> _archive; #else - boost::scoped_ptr<boost::archive::text_iarchive> _archive; + boost::scoped_ptr<boost::archive::text_iarchive> _archive; #endif }; -class boost_serialization_archive_utils { +class boost_serialization_archive_utils +{ public: - static int32_t get_version() { - #if (USE_BINARY_ARCHIVE) + static int32_t get_version() + { +#if (USE_BINARY_ARCHIVE) typedef boost::archive::binary_oarchive archive_t; - #else - typedef boost::archive::text_oarchive archive_t; - #endif +#else + typedef boost::archive::text_oarchive archive_t; +#endif std::ostringstream stream; archive_t dummy_archive(stream, boost::archive::no_header); return static_cast<int32_t>(dummy_archive.get_library_version()); } }; -}} +}} // namespace uhd::usrprio_rpc #undef USE_BINARY_ARCHIVE diff --git a/host/include/uhd/transport/nirio/rpc/usrprio_rpc_client.hpp b/host/include/uhd/transport/nirio/rpc/usrprio_rpc_client.hpp index b05cf0d5d..1d67d9286 100644 --- a/host/include/uhd/transport/nirio/rpc/usrprio_rpc_client.hpp +++ b/host/include/uhd/transport/nirio/rpc/usrprio_rpc_client.hpp @@ -8,51 +8,47 @@ #ifndef INCLUDED_USRPRIO_RPC_CLIENT_HPP #define INCLUDED_USRPRIO_RPC_CLIENT_HPP -#include <uhd/transport/nirio/rpc/rpc_common.hpp> #include <uhd/transport/nirio/rpc/rpc_client.hpp> +#include <uhd/transport/nirio/rpc/rpc_common.hpp> #include <uhd/transport/nirio/rpc/usrprio_rpc_common.hpp> #include <uhd/transport/nirio/status.h> namespace uhd { namespace usrprio_rpc { -class UHD_API usrprio_rpc_client { +class UHD_API usrprio_rpc_client +{ public: - usrprio_rpc_client( - std::string server, - std::string port); + usrprio_rpc_client(std::string server, std::string port); ~usrprio_rpc_client(); - inline void set_rpc_timeout(boost::posix_time::milliseconds timeout_in_ms) { + inline void set_rpc_timeout(boost::posix_time::milliseconds timeout_in_ms) + { _timeout = timeout_in_ms; } - inline nirio_status get_ctor_status() { + inline nirio_status get_ctor_status() + { return _ctor_status; } - nirio_status niusrprio_enumerate( - NIUSRPRIO_ENUMERATE_ARGS); - nirio_status niusrprio_open_session( - NIUSRPRIO_OPEN_SESSION_ARGS); - nirio_status niusrprio_close_session( - NIUSRPRIO_CLOSE_SESSION_ARGS); - nirio_status niusrprio_reset_device( - NIUSRPRIO_RESET_SESSION_ARGS); + nirio_status niusrprio_enumerate(NIUSRPRIO_ENUMERATE_ARGS); + nirio_status niusrprio_open_session(NIUSRPRIO_OPEN_SESSION_ARGS); + nirio_status niusrprio_close_session(NIUSRPRIO_CLOSE_SESSION_ARGS); + nirio_status niusrprio_reset_device(NIUSRPRIO_RESET_SESSION_ARGS); nirio_status niusrprio_download_bitstream_to_fpga( NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA_ARGS); - nirio_status niusrprio_get_interface_path( - NIUSRPRIO_GET_INTERFACE_PATH_ARGS); - nirio_status niusrprio_download_fpga_to_flash( - NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS); + nirio_status niusrprio_get_interface_path(NIUSRPRIO_GET_INTERFACE_PATH_ARGS); + nirio_status niusrprio_download_fpga_to_flash(NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS); private: - static nirio_status _boost_error_to_nirio_status(const boost::system::error_code& err); + static nirio_status _boost_error_to_nirio_status( + const boost::system::error_code& err); - rpc_client _rpc_client; + rpc_client _rpc_client; boost::posix_time::milliseconds _timeout; - nirio_status _ctor_status; + nirio_status _ctor_status; }; -}} +}} // namespace uhd::usrprio_rpc #endif /* INCLUDED_USRPRIO_RPC_CLIENT_HPP */ diff --git a/host/include/uhd/transport/nirio/rpc/usrprio_rpc_common.hpp b/host/include/uhd/transport/nirio/rpc/usrprio_rpc_common.hpp index 12cf5f385..71d8f7047 100644 --- a/host/include/uhd/transport/nirio/rpc/usrprio_rpc_common.hpp +++ b/host/include/uhd/transport/nirio/rpc/usrprio_rpc_common.hpp @@ -12,9 +12,9 @@ namespace uhd { namespace usrprio_rpc { -//Function IDs +// Function IDs -static const func_id_t NIUSRPRIO_FUNC_BASE = 0x100; +static const func_id_t NIUSRPRIO_FUNC_BASE = 0x100; static const func_id_t NIUSRPRIO_ENUMERATE = NIUSRPRIO_FUNC_BASE + 0; static const func_id_t NIUSRPRIO_OPEN_SESSION = NIUSRPRIO_FUNC_BASE + 1; @@ -24,52 +24,44 @@ static const func_id_t NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA = NIUSRPRIO_FUNC_BAS static const func_id_t NIUSRPRIO_GET_INTERFACE_PATH = NIUSRPRIO_FUNC_BASE + 5; static const func_id_t NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH = NIUSRPRIO_FUNC_BASE + 6; -//Function Args +// Function Args -struct usrprio_device_info { +struct usrprio_device_info +{ uint32_t interface_num; - std::string resource_name; - std::string pcie_serial_num; - std::string interface_path; + std::string resource_name; + std::string pcie_serial_num; + std::string interface_path; - template <typename Archive> - void serialize(Archive& ar, const unsigned int version) + template <typename Archive> void serialize(Archive& ar, const unsigned int version) { - if (version || !version) { //Suppress unused warning - ar & interface_num; - ar & resource_name; - ar & pcie_serial_num; - ar & interface_path; + if (version || !version) { // Suppress unused warning + ar& interface_num; + ar& resource_name; + ar& pcie_serial_num; + ar& interface_path; } } }; typedef std::vector<usrprio_device_info> usrprio_device_info_vtr; -#define NIUSRPRIO_ENUMERATE_ARGS \ - usrprio_device_info_vtr& device_info_vtr +#define NIUSRPRIO_ENUMERATE_ARGS usrprio_device_info_vtr& device_info_vtr -#define NIUSRPRIO_OPEN_SESSION_ARGS \ - const std::string& resource, \ - const std::string& path, \ - const std::string& signature, \ - const uint16_t& download_fpga +#define NIUSRPRIO_OPEN_SESSION_ARGS \ + const std::string &resource, const std::string &path, const std::string &signature, \ + const uint16_t &download_fpga -#define NIUSRPRIO_CLOSE_SESSION_ARGS \ - const std::string& resource +#define NIUSRPRIO_CLOSE_SESSION_ARGS const std::string& resource -#define NIUSRPRIO_RESET_SESSION_ARGS \ - const std::string& resource +#define NIUSRPRIO_RESET_SESSION_ARGS const std::string& resource -#define NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA_ARGS \ - const std::string& resource +#define NIUSRPRIO_DOWNLOAD_BITSTREAM_TO_FPGA_ARGS const std::string& resource -#define NIUSRPRIO_GET_INTERFACE_PATH_ARGS \ - const std::string& resource, \ - std::string& interface_path +#define NIUSRPRIO_GET_INTERFACE_PATH_ARGS \ + const std::string &resource, std::string &interface_path -#define NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS \ - const std::string& resource, \ - const std::string& bitstream_path -}} +#define NIUSRPRIO_DOWNLOAD_FPGA_TO_FLASH_ARGS \ + const std::string &resource, const std::string &bitstream_path +}} // namespace uhd::usrprio_rpc #endif /* INCLUDED_USRPRIO_RPC_COMMON_HPP */ diff --git a/host/include/uhd/transport/nirio_zero_copy.hpp b/host/include/uhd/transport/nirio_zero_copy.hpp index bc055d636..b5e4dea38 100644 --- a/host/include/uhd/transport/nirio_zero_copy.hpp +++ b/host/include/uhd/transport/nirio_zero_copy.hpp @@ -8,27 +8,26 @@ #ifndef INCLUDED_UHD_TRANSPORT_NIRIO_ZERO_COPY_HPP #define INCLUDED_UHD_TRANSPORT_NIRIO_ZERO_COPY_HPP -#include <uhd/transport/nirio/niusrprio_session.h> #include <uhd/config.hpp> +#include <uhd/transport/nirio/niusrprio_session.h> #include <uhd/transport/zero_copy.hpp> #include <uhd/types/device_addr.hpp> -#include <boost/shared_ptr.hpp> #include <stdint.h> +#include <boost/shared_ptr.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { -class UHD_API nirio_zero_copy : public virtual zero_copy_if{ +class UHD_API nirio_zero_copy : public virtual zero_copy_if +{ public: typedef boost::shared_ptr<nirio_zero_copy> sptr; - static sptr make( - uhd::niusrprio::niusrprio_session::sptr fpga_session, + static sptr make(uhd::niusrprio::niusrprio_session::sptr fpga_session, const uint32_t instance, - const zero_copy_xport_params &default_buff_args, - const device_addr_t &hints = device_addr_t() - ); + const zero_copy_xport_params& default_buff_args, + const device_addr_t& hints = device_addr_t()); }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_NIRIO_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/tcp_zero_copy.hpp b/host/include/uhd/transport/tcp_zero_copy.hpp index d250f675a..4db68cec8 100644 --- a/host/include/uhd/transport/tcp_zero_copy.hpp +++ b/host/include/uhd/transport/tcp_zero_copy.hpp @@ -13,7 +13,7 @@ #include <uhd/types/device_addr.hpp> #include <boost/shared_ptr.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { /*! * The zero copy TCP transport. @@ -37,13 +37,11 @@ struct UHD_API tcp_zero_copy : public virtual zero_copy_if * \param port a string representing the destination port * \param hints optional parameters to pass to the underlying transport */ - static zero_copy_if::sptr make( - const std::string &addr, - const std::string &port, - const device_addr_t &hints = device_addr_t() - ); + static zero_copy_if::sptr make(const std::string& addr, + const std::string& port, + const device_addr_t& hints = device_addr_t()); }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_TCP_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/udp_constants.hpp b/host/include/uhd/transport/udp_constants.hpp index 5d3f5dea0..6fe26424f 100644 --- a/host/include/uhd/transport/udp_constants.hpp +++ b/host/include/uhd/transport/udp_constants.hpp @@ -10,7 +10,8 @@ // Constants related to UDP (over Ethernet) -static const size_t IP_PROTOCOL_MIN_MTU_SIZE = 576; //bytes -static const size_t IP_PROTOCOL_UDP_PLUS_IP_HEADER = 28; //bytes. Note that this is the minimum value! +static const size_t IP_PROTOCOL_MIN_MTU_SIZE = 576; // bytes +static const size_t IP_PROTOCOL_UDP_PLUS_IP_HEADER = + 28; // bytes. Note that this is the minimum value! #endif /* INCLUDED_UHD_TRANSPORT_UDP_CONSTANTS_HPP */ diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index 3683ed8e0..19164d80b 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -11,19 +11,21 @@ #include <uhd/config.hpp> #include <uhd/types/serial.hpp> #include <boost/asio/buffer.hpp> -#include <boost/utility.hpp> #include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { -class UHD_API udp_simple : boost::noncopyable{ +class UHD_API udp_simple : boost::noncopyable +{ public: typedef boost::shared_ptr<udp_simple> sptr; virtual ~udp_simple(void) = 0; //! The maximum number of bytes per udp packet. - static const size_t mtu = 1500 - 20 - 8; //default ipv4 mtu - ipv4 header - udp header + static const size_t mtu = 1500 - 20 - 8; // default ipv4 mtu - ipv4 header - udp + // header /*! * Make a new connected udp transport: @@ -38,7 +40,7 @@ public: * \param addr a string representing the destination address * \param port a string representing the destination port */ - static sptr make_connected(const std::string &addr, const std::string &port); + static sptr make_connected(const std::string& addr, const std::string& port); /*! * Make a new broadcasting udp transport: @@ -52,7 +54,7 @@ public: * \param addr a string representing the destination address * \param port a string representing the destination port */ - static sptr make_broadcast(const std::string &addr, const std::string &port); + static sptr make_broadcast(const std::string& addr, const std::string& port); /*! * Make a UART interface from a UDP transport. @@ -67,7 +69,7 @@ public: * \param buff single asio buffer * \return the number of bytes sent */ - virtual size_t send(const boost::asio::const_buffer &buff) = 0; + virtual size_t send(const boost::asio::const_buffer& buff) = 0; /*! * Receive into the provided buffer. @@ -76,7 +78,8 @@ public: * \param timeout the timeout in seconds * \return the number of bytes received or zero on timeout */ - virtual size_t recv(const boost::asio::mutable_buffer &buff, double timeout = 0.1) = 0; + virtual size_t recv( + const boost::asio::mutable_buffer& buff, double timeout = 0.1) = 0; /*! * Get the last IP address as seen by recv(). @@ -90,6 +93,6 @@ public: virtual std::string get_send_addr(void) = 0; }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP */ diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index ff55a58da..2fedad99a 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -13,7 +13,7 @@ #include <uhd/types/device_addr.hpp> #include <boost/shared_ptr.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { /*! * A zero copy udp transport provides an efficient way to handle data. @@ -25,11 +25,13 @@ namespace uhd{ namespace transport{ * If no platform specific solution is available, make returns a boost asio * implementation that wraps the functionality around a standard send/recv calls. */ -class UHD_API udp_zero_copy : public virtual zero_copy_if{ +class UHD_API udp_zero_copy : public virtual zero_copy_if +{ public: - struct buff_params { - size_t recv_buff_size; - size_t send_buff_size; + struct buff_params + { + size_t recv_buff_size; + size_t send_buff_size; }; typedef boost::shared_ptr<udp_zero_copy> sptr; @@ -50,13 +52,11 @@ public: * \param[out] buff_params_out Returns the actual buffer sizes * \param hints optional parameters to pass to the underlying transport */ - static sptr make( - const std::string &addr, - const std::string &port, - const zero_copy_xport_params &default_buff_args, + static sptr make(const std::string& addr, + const std::string& port, + const zero_copy_xport_params& default_buff_args, udp_zero_copy::buff_params& buff_params_out, - const device_addr_t &hints = device_addr_t() - ); + const device_addr_t& hints = device_addr_t()); /*! Return the local port of the UDP connection * @@ -74,6 +74,6 @@ public: virtual std::string get_local_addr(void) const = 0; }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/usb_control.hpp b/host/include/uhd/transport/usb_control.hpp index 53c35881a..3fc6d0394 100644 --- a/host/include/uhd/transport/usb_control.hpp +++ b/host/include/uhd/transport/usb_control.hpp @@ -12,7 +12,8 @@ namespace uhd { namespace transport { -class UHD_API usb_control : boost::noncopyable { +class UHD_API usb_control : boost::noncopyable +{ public: typedef boost::shared_ptr<usb_control> sptr; @@ -47,14 +48,14 @@ public: * \return number of bytes submitted or error code */ virtual int submit(uint8_t request_type, - uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length, - uint32_t timeout = 0) = 0; + uint8_t request, + uint16_t value, + uint16_t index, + unsigned char* buff, + uint16_t length, + uint32_t timeout = 0) = 0; }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP */ diff --git a/host/include/uhd/transport/usb_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp index 9b0806b30..3cd740771 100644 --- a/host/include/uhd/transport/usb_device_handle.hpp +++ b/host/include/uhd/transport/usb_device_handle.hpp @@ -9,9 +9,9 @@ #define INCLUDED_UHD_TRANSPORT_USB_DEVICE_HANDLE_HPP #include <uhd/config.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> #include <stdint.h> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> #include <vector> namespace uhd { namespace transport { @@ -28,7 +28,8 @@ namespace uhd { namespace transport { * a true descriptor serial number string. This interface returns the * actual string descriptor. */ -class UHD_API usb_device_handle : boost::noncopyable { +class UHD_API usb_device_handle : boost::noncopyable +{ public: typedef boost::shared_ptr<usb_device_handle> sptr; typedef std::pair<uint16_t, uint16_t> vid_pid_pair_t; @@ -75,12 +76,14 @@ public: * Return a vector of USB devices on this host * \return a vector of USB device handles that match vid and pid */ - static std::vector<usb_device_handle::sptr> get_device_list(uint16_t vid, uint16_t pid); - static std::vector<usb_device_handle::sptr> get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list); + static std::vector<usb_device_handle::sptr> get_device_list( + uint16_t vid, uint16_t pid); + static std::vector<usb_device_handle::sptr> get_device_list( + const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list); -}; //namespace usb +}; // namespace usb -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_USB_DEVICE_HANDLE_HPP */ diff --git a/host/include/uhd/transport/usb_zero_copy.hpp b/host/include/uhd/transport/usb_zero_copy.hpp index 7ce85e54a..d78807768 100644 --- a/host/include/uhd/transport/usb_zero_copy.hpp +++ b/host/include/uhd/transport/usb_zero_copy.hpp @@ -24,7 +24,8 @@ namespace uhd { namespace transport { * If no platform specific solution is available, make returns a boost asio * implementation that wraps functionality around standard send/recv calls. */ -class UHD_API usb_zero_copy : public virtual zero_copy_if { +class UHD_API usb_zero_copy : public virtual zero_copy_if +{ public: typedef boost::shared_ptr<usb_zero_copy> sptr; @@ -45,16 +46,14 @@ public: * \param hints optional parameters to pass to the underlying transport * \return a new zero copy USB object */ - static sptr make( - usb_device_handle::sptr handle, + static sptr make(usb_device_handle::sptr handle, const int recv_interface, const unsigned char recv_endpoint, const int send_interface, const unsigned char send_endpoint, - const device_addr_t &hints = device_addr_t() - ); + const device_addr_t& hints = device_addr_t()); }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp index 07792f13f..f357b8ceb 100644 --- a/host/include/uhd/transport/vrt_if_packet.hpp +++ b/host/include/uhd/transport/vrt_if_packet.hpp @@ -12,191 +12,189 @@ #include <stdint.h> #include <cstddef> //size_t -namespace uhd{ namespace transport{ - -namespace vrt{ - - //! The maximum number of 32-bit words in the vrlp link layer - static const size_t num_vrl_words32 = 3; - - //! The maximum number of 32-bit words in a vrt if packet header - static const size_t max_if_hdr_words32 = 7; //hdr+sid+cid+tsi+tsf - - /*! - * Definition for fields that can be packed into a vrt if header. - * The size fields are used for input and output depending upon - * the operation used (ie the pack or unpack function call). - */ - struct UHD_API if_packet_info_t - { - if_packet_info_t(void); - - //link layer type - always set for pack and unpack - enum link_type_t - { - LINK_TYPE_NONE = 0x0, - LINK_TYPE_CHDR = 0x1, - LINK_TYPE_VRLP = 0x2 - } link_type; - - //packet type - enum packet_type_t - { - // VRT language: - PACKET_TYPE_DATA = 0x0, - PACKET_TYPE_IF_EXT = 0x1, - PACKET_TYPE_CONTEXT = 0x2, //extension context: has_sid = true - - // CHDR language: - //PACKET_TYPE_DATA = 0x0, // Data - PACKET_TYPE_FC = 0x1, // Flow control - PACKET_TYPE_ACK = 0x1, // Flow control (ack) - PACKET_TYPE_CMD = 0x2, // Command - PACKET_TYPE_RESP = 0x3, // Command response - PACKET_TYPE_ERROR = 0x3 // Command response: Error (the EOB bit is raised in this case) - } packet_type; - - //size fields - size_t num_payload_words32; //required in pack, derived in unpack - size_t num_payload_bytes; //required in pack, derived in unpack - size_t num_header_words32; //derived in pack, derived in unpack - size_t num_packet_words32; //derived in pack, required in unpack - - //header fields - size_t packet_count; - //! Asserted for start- or end-of-burst - bool sob, eob; - //! This is asserted for command responses that are errors (CHDR only) - bool error; - //! This is asserted for flow control packets are ACKS (CHDR only) - bool fc_ack; - - //optional fields - //! Stream ID (SID). See uhd::sid_t - bool has_sid; uint32_t sid; - //! Class ID. - bool has_cid; uint64_t cid; - //! Integer timestamp - bool has_tsi; uint32_t tsi; - //! Fractional timestamp - bool has_tsf; uint64_t tsf; - //! Trailer - bool has_tlr; uint32_t tlr; - }; - - /*! - * Pack a vrt header from metadata (big endian format). - * - * \section vrt_pack_contract Packing contract - * - * \subsection vrt_pack_contract_reqs Requirements: - * - packet_buff points to a valid address space with enough space to write - * the entire buffer, regardless of its length. At the very least, it must - * be able to hold an entire header. - * - `if_packet_info` has the following members set to correct values: - * - `has_*` members all set accordingly - * - For every true `has_*` member, the corresponding variable holds a valid - * value (e.g. if `has_sid` is true, `sid` contains a valid SID) - * - `num_payload_bytes` and `num_payload_words32` are both set to the correct values - * - * \subsection vrt_pack_contract_res Result: - * - `packet_buff` now points to a valid header that can be sent over the transport - * without further modification - * - The following members on `if_packet_info` are set: - * - `num_header_words32` - * - `num_packet_words32` - * - * \param packet_buff memory to write the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_pack_be( - uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - /*! - * Unpack a vrt header to metadata (big endian format). - * - * \section vrt_unpack_contract Unpacking contract - * - * \subsection vrt_unpack_contract_reqs Requirements - * - `packet_buff` points to a readable address space with a - * CHDR packet, starting at the header. `packet_buff[0]` *must* always - * point to a valid first word of the header. This implies that num_packet_words32 - * must be at least 1. - * - `if_packet_info` has the following members set to correct values: - * - `num_packet_words32`. This means all values `packet_buff[0]` - * through `packet_buff[if_packet_info.num_packet_words32-1]` are - * readable words from this packet. - * - `link_type` - * - * \subsection vrt_unpack_contract_res Result - * - `if_packet_info` now has the following values set to correct values: - * - `packet_type` - * - `num_payload_bytes` - * - `num_payload_words32` - * - `num_header_words32` - * - `has_*` - * - `sob`, `eob`, `error`, `cid`, `sid` (if applicable) - * - `tsf`, `tsi` (if applicable) - * - * \subsection Exceptions - * - If the header is invalid, but the requirements are still met, - * will throw a uhd::value_error. - * - * \param packet_buff memory to read the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_unpack_be( - const uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - /*! - * Pack a vrt header from metadata (little endian format). - * - * See \ref vrt_pack_contract. - * - * \param packet_buff memory to write the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_pack_le( - uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - /*! - * Unpack a vrt header to metadata (little endian format). - * - * See \ref vrt_unpack_contract. - * - * \param packet_buff memory to read the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_unpack_le( - const uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - UHD_INLINE if_packet_info_t::if_packet_info_t(void): - link_type(LINK_TYPE_NONE), - packet_type(PACKET_TYPE_DATA), - num_payload_words32(0), - num_payload_bytes(0), - num_header_words32(0), - num_packet_words32(0), - packet_count(0), - sob(false), eob(false), - error(false), fc_ack(false), - has_sid(false), sid(0), - has_cid(false), cid(0), - has_tsi(false), tsi(0), - has_tsf(false), tsf(0), - has_tlr(false), tlr(0) - {} - -} //namespace vrt - -}} //namespace +namespace uhd { namespace transport { namespace vrt { + +//! The maximum number of 32-bit words in the vrlp link layer +static const size_t num_vrl_words32 = 3; + +//! The maximum number of 32-bit words in a vrt if packet header +static const size_t max_if_hdr_words32 = 7; // hdr+sid+cid+tsi+tsf + +/*! + * Definition for fields that can be packed into a vrt if header. + * The size fields are used for input and output depending upon + * the operation used (ie the pack or unpack function call). + */ +struct UHD_API if_packet_info_t +{ + if_packet_info_t(void); + + // link layer type - always set for pack and unpack + enum link_type_t { + LINK_TYPE_NONE = 0x0, + LINK_TYPE_CHDR = 0x1, + LINK_TYPE_VRLP = 0x2 + } link_type; + + // packet type + enum packet_type_t { + // VRT language: + PACKET_TYPE_DATA = 0x0, + PACKET_TYPE_IF_EXT = 0x1, + PACKET_TYPE_CONTEXT = 0x2, // extension context: has_sid = true + + // CHDR language: + // PACKET_TYPE_DATA = 0x0, // Data + PACKET_TYPE_FC = 0x1, // Flow control + PACKET_TYPE_ACK = 0x1, // Flow control (ack) + PACKET_TYPE_CMD = 0x2, // Command + PACKET_TYPE_RESP = 0x3, // Command response + PACKET_TYPE_ERROR = + 0x3 // Command response: Error (the EOB bit is raised in this case) + } packet_type; + + // size fields + size_t num_payload_words32; // required in pack, derived in unpack + size_t num_payload_bytes; // required in pack, derived in unpack + size_t num_header_words32; // derived in pack, derived in unpack + size_t num_packet_words32; // derived in pack, required in unpack + + // header fields + size_t packet_count; + //! Asserted for start- or end-of-burst + bool sob, eob; + //! This is asserted for command responses that are errors (CHDR only) + bool error; + //! This is asserted for flow control packets are ACKS (CHDR only) + bool fc_ack; + + // optional fields + //! Stream ID (SID). See uhd::sid_t + bool has_sid; + uint32_t sid; + //! Class ID. + bool has_cid; + uint64_t cid; + //! Integer timestamp + bool has_tsi; + uint32_t tsi; + //! Fractional timestamp + bool has_tsf; + uint64_t tsf; + //! Trailer + bool has_tlr; + uint32_t tlr; +}; + +/*! + * Pack a vrt header from metadata (big endian format). + * + * \section vrt_pack_contract Packing contract + * + * \subsection vrt_pack_contract_reqs Requirements: + * - packet_buff points to a valid address space with enough space to write + * the entire buffer, regardless of its length. At the very least, it must + * be able to hold an entire header. + * - `if_packet_info` has the following members set to correct values: + * - `has_*` members all set accordingly + * - For every true `has_*` member, the corresponding variable holds a valid + * value (e.g. if `has_sid` is true, `sid` contains a valid SID) + * - `num_payload_bytes` and `num_payload_words32` are both set to the correct values + * + * \subsection vrt_pack_contract_res Result: + * - `packet_buff` now points to a valid header that can be sent over the transport + * without further modification + * - The following members on `if_packet_info` are set: + * - `num_header_words32` + * - `num_packet_words32` + * + * \param packet_buff memory to write the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_pack_be(uint32_t* packet_buff, if_packet_info_t& if_packet_info); + +/*! + * Unpack a vrt header to metadata (big endian format). + * + * \section vrt_unpack_contract Unpacking contract + * + * \subsection vrt_unpack_contract_reqs Requirements + * - `packet_buff` points to a readable address space with a + * CHDR packet, starting at the header. `packet_buff[0]` *must* always + * point to a valid first word of the header. This implies that num_packet_words32 + * must be at least 1. + * - `if_packet_info` has the following members set to correct values: + * - `num_packet_words32`. This means all values `packet_buff[0]` + * through `packet_buff[if_packet_info.num_packet_words32-1]` are + * readable words from this packet. + * - `link_type` + * + * \subsection vrt_unpack_contract_res Result + * - `if_packet_info` now has the following values set to correct values: + * - `packet_type` + * - `num_payload_bytes` + * - `num_payload_words32` + * - `num_header_words32` + * - `has_*` + * - `sob`, `eob`, `error`, `cid`, `sid` (if applicable) + * - `tsf`, `tsi` (if applicable) + * + * \subsection Exceptions + * - If the header is invalid, but the requirements are still met, + * will throw a uhd::value_error. + * + * \param packet_buff memory to read the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_unpack_be( + const uint32_t* packet_buff, if_packet_info_t& if_packet_info); + +/*! + * Pack a vrt header from metadata (little endian format). + * + * See \ref vrt_pack_contract. + * + * \param packet_buff memory to write the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_pack_le(uint32_t* packet_buff, if_packet_info_t& if_packet_info); + +/*! + * Unpack a vrt header to metadata (little endian format). + * + * See \ref vrt_unpack_contract. + * + * \param packet_buff memory to read the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ +UHD_API void if_hdr_unpack_le( + const uint32_t* packet_buff, if_packet_info_t& if_packet_info); + +UHD_INLINE if_packet_info_t::if_packet_info_t(void) + : link_type(LINK_TYPE_NONE) + , packet_type(PACKET_TYPE_DATA) + , num_payload_words32(0) + , num_payload_bytes(0) + , num_header_words32(0) + , num_packet_words32(0) + , packet_count(0) + , sob(false) + , eob(false) + , error(false) + , fc_ack(false) + , has_sid(false) + , sid(0) + , has_cid(false) + , cid(0) + , has_tsi(false) + , tsi(0) + , has_tsf(false) + , tsf(0) + , has_tlr(false) + , tlr(0) +{ +} + +}}} // namespace uhd::transport::vrt #endif /* INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP */ diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index 4218ab2f9..05582f902 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -9,199 +9,212 @@ #define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP #include <uhd/config.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/intrusive_ptr.hpp> #include <boost/detail/atomic_count.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { - //! Simple managed buffer with release interface - class UHD_API managed_buffer{ - public: - managed_buffer(void):_ref_count(0),_buffer(NULL),_length(0) - { +//! Simple managed buffer with release interface +class UHD_API managed_buffer +{ +public: + managed_buffer(void) : _ref_count(0), _buffer(NULL), _length(0) + { #ifdef UHD_TXRX_DEBUG_PRINTS - _mb_num = s_buffer_count; - // From Boost website: atomic_count seems only to have precrement operator. - ++s_buffer_count; + _mb_num = s_buffer_count; + // From Boost website: atomic_count seems only to have precrement operator. + ++s_buffer_count; #endif - } - - virtual ~managed_buffer(void) {} - - /*! - * Signal to the transport that we are done with the buffer. - * This should be called to release the buffer to the transport object. - * After calling, the referenced memory should be considered invalid. - */ - virtual void release(void) = 0; - - /*! - * Use commit() to re-write the length (for use with send buffers). - * \param num_bytes the number of bytes written into the buffer - */ - UHD_INLINE void commit(size_t num_bytes){ - _length = num_bytes; - } - - /*! - * Get a pointer to the underlying buffer. - * \return a pointer into memory - */ - template <class T> UHD_INLINE T cast(void) const{ - return static_cast<T>(_buffer); - } - - /*! - * Get the size of the underlying buffer. - * \return the number of bytes - */ - UHD_INLINE size_t size(void) const{ - return _length; - } - - //! Create smart pointer to a reusable managed buffer - template <typename T> UHD_INLINE boost::intrusive_ptr<T> make( - T *p, void *buffer, size_t length - ){ - _buffer = buffer; - _length = length; - return boost::intrusive_ptr<T>(p); - } - - boost::detail::atomic_count _ref_count; - typedef boost::intrusive_ptr<managed_buffer> sptr; - - int ref_count(){ - return (int) _ref_count; - } + } + + virtual ~managed_buffer(void) {} + + /*! + * Signal to the transport that we are done with the buffer. + * This should be called to release the buffer to the transport object. + * After calling, the referenced memory should be considered invalid. + */ + virtual void release(void) = 0; + + /*! + * Use commit() to re-write the length (for use with send buffers). + * \param num_bytes the number of bytes written into the buffer + */ + UHD_INLINE void commit(size_t num_bytes) + { + _length = num_bytes; + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template <class T> UHD_INLINE T cast(void) const + { + return static_cast<T>(_buffer); + } + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + UHD_INLINE size_t size(void) const + { + return _length; + } + + //! Create smart pointer to a reusable managed buffer + template <typename T> + UHD_INLINE boost::intrusive_ptr<T> make(T* p, void* buffer, size_t length) + { + _buffer = buffer; + _length = length; + return boost::intrusive_ptr<T>(p); + } + + boost::detail::atomic_count _ref_count; + typedef boost::intrusive_ptr<managed_buffer> sptr; + + int ref_count() + { + return (int)_ref_count; + } #ifdef UHD_TXRX_DEBUG_PRINTS - int num() const{ - return _mb_num; - } + int num() const + { + return _mb_num; + } #endif - protected: - void *_buffer; - size_t _length; +protected: + void* _buffer; + size_t _length; #ifdef UHD_TXRX_DEBUG_PRINTS - int _mb_num; + int _mb_num; #endif - private: +private: #ifdef UHD_TXRX_DEBUG_PRINTS - static boost::detail::atomic_count s_buffer_count; + static boost::detail::atomic_count s_buffer_count; #endif - }; - - UHD_INLINE void intrusive_ptr_add_ref(managed_buffer *p){ - ++(p->_ref_count); +}; + +UHD_INLINE void intrusive_ptr_add_ref(managed_buffer* p) +{ + ++(p->_ref_count); +} + +UHD_INLINE void intrusive_ptr_release(managed_buffer* p) +{ + if (--(p->_ref_count) == 0) + p->release(); +} + +/*! + * A managed receive buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after reading. + */ +class UHD_API managed_recv_buffer : public managed_buffer +{ +public: + typedef boost::intrusive_ptr<managed_recv_buffer> sptr; +}; + +/*! + * A managed send buffer: + * Contains a reference to transport-managed memory, + * and a method to commit the memory after writing. + */ +class UHD_API managed_send_buffer : public managed_buffer +{ +public: + typedef boost::intrusive_ptr<managed_send_buffer> sptr; +}; + +/*! + * Transport parameters + */ +struct zero_copy_xport_params +{ + zero_copy_xport_params() + : recv_frame_size(0) + , send_frame_size(0) + , num_recv_frames(0) + , num_send_frames(0) + , recv_buff_size(0) + , send_buff_size(0) + { /* NOP */ } + size_t recv_frame_size; + size_t send_frame_size; + size_t num_recv_frames; + size_t num_send_frames; + size_t recv_buff_size; + size_t send_buff_size; +}; + +/*! + * A zero-copy interface for transport objects. + * Provides a way to get send and receive buffers + * with memory managed by the transport object. + */ +class UHD_API zero_copy_if : boost::noncopyable +{ +public: + typedef boost::shared_ptr<zero_copy_if> sptr; - UHD_INLINE void intrusive_ptr_release(managed_buffer *p){ - if (--(p->_ref_count) == 0) p->release(); - } + /*! + * Clean up tasks before releasing the transport object. + */ + virtual ~zero_copy_if(){}; + + /*! + * Get a new receive buffer from this transport object. + * \param timeout the timeout to get the buffer in seconds + * \return a managed buffer, or null sptr on timeout/error + */ + virtual managed_recv_buffer::sptr get_recv_buff(double timeout = 0.1) = 0; /*! - * A managed receive buffer: - * Contains a reference to transport-managed memory, - * and a method to release the memory after reading. + * Get the number of receive frames: + * The number of simultaneous receive buffers in use. + * \return number of frames */ - class UHD_API managed_recv_buffer : public managed_buffer{ - public: - typedef boost::intrusive_ptr<managed_recv_buffer> sptr; - }; + virtual size_t get_num_recv_frames(void) const = 0; /*! - * A managed send buffer: - * Contains a reference to transport-managed memory, - * and a method to commit the memory after writing. + * Get the size of a receive frame: + * The maximum capacity of a single receive buffer. + * \return frame size in bytes */ - class UHD_API managed_send_buffer : public managed_buffer{ - public: - typedef boost::intrusive_ptr<managed_send_buffer> sptr; - }; + virtual size_t get_recv_frame_size(void) const = 0; /*! - * Transport parameters + * Get a new send buffer from this transport object. + * \param timeout the timeout to get the buffer in seconds + * \return a managed buffer, or null sptr on timeout/error */ - struct zero_copy_xport_params { - zero_copy_xport_params() : - recv_frame_size(0), - send_frame_size(0), - num_recv_frames(0), - num_send_frames(0), - recv_buff_size(0), - send_buff_size(0) - { /* NOP */ } - size_t recv_frame_size; - size_t send_frame_size; - size_t num_recv_frames; - size_t num_send_frames; - size_t recv_buff_size; - size_t send_buff_size; - }; + virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 0; /*! - * A zero-copy interface for transport objects. - * Provides a way to get send and receive buffers - * with memory managed by the transport object. + * Get the number of send frames: + * The number of simultaneous send buffers in use. + * \return number of frames */ - class UHD_API zero_copy_if : boost::noncopyable{ - public: - typedef boost::shared_ptr<zero_copy_if> sptr; - - /*! - * Clean up tasks before releasing the transport object. - */ - virtual ~zero_copy_if() {}; - - /*! - * Get a new receive buffer from this transport object. - * \param timeout the timeout to get the buffer in seconds - * \return a managed buffer, or null sptr on timeout/error - */ - virtual managed_recv_buffer::sptr get_recv_buff(double timeout = 0.1) = 0; - - /*! - * Get the number of receive frames: - * The number of simultaneous receive buffers in use. - * \return number of frames - */ - virtual size_t get_num_recv_frames(void) const = 0; - - /*! - * Get the size of a receive frame: - * The maximum capacity of a single receive buffer. - * \return frame size in bytes - */ - virtual size_t get_recv_frame_size(void) const = 0; - - /*! - * Get a new send buffer from this transport object. - * \param timeout the timeout to get the buffer in seconds - * \return a managed buffer, or null sptr on timeout/error - */ - virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 0; - - /*! - * Get the number of send frames: - * The number of simultaneous send buffers in use. - * \return number of frames - */ - virtual size_t get_num_send_frames(void) const = 0; - - /*! - * Get the size of a send frame: - * The maximum capacity of a single send buffer. - * \return frame size in bytes - */ - virtual size_t get_send_frame_size(void) const = 0; - - }; - -}} //namespace + virtual size_t get_num_send_frames(void) const = 0; + + /*! + * Get the size of a send frame: + * The maximum capacity of a single send buffer. + * \return frame size in bytes + */ + virtual size_t get_send_frame_size(void) const = 0; +}; + +}} // namespace uhd::transport #endif /* INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/zero_copy_flow_ctrl.hpp b/host/include/uhd/transport/zero_copy_flow_ctrl.hpp index bc99e9bbf..f98a0891c 100644 --- a/host/include/uhd/transport/zero_copy_flow_ctrl.hpp +++ b/host/include/uhd/transport/zero_copy_flow_ctrl.hpp @@ -13,7 +13,7 @@ #include <boost/function.hpp> #include <boost/shared_ptr.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { /*! * Flow control function. @@ -25,7 +25,8 @@ typedef boost::function<bool(managed_buffer::sptr buff)> flow_ctrl_func; /*! * Adds flow control to any zero_copy_if transport. */ -class UHD_API zero_copy_flow_ctrl : public virtual zero_copy_if { +class UHD_API zero_copy_flow_ctrl : public virtual zero_copy_if +{ public: typedef boost::shared_ptr<zero_copy_flow_ctrl> sptr; @@ -33,16 +34,15 @@ public: * Make flow controlled transport. * * \param transport a shared pointer to the transport interface - * \param send_flow_ctrl optional send flow control function called before buffer is sent - * \param recv_flow_ctrl optional receive flow control function called after buffer released + * \param send_flow_ctrl optional send flow control function called before buffer is + * sent \param recv_flow_ctrl optional receive flow control function called after + * buffer released */ - static sptr make( - zero_copy_if::sptr transport, + static sptr make(zero_copy_if::sptr transport, flow_ctrl_func send_flow_ctrl, - flow_ctrl_func recv_flow_ctrl - ); + flow_ctrl_func recv_flow_ctrl); }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_ZERO_COPY_FLOW_CTRL_HPP */ diff --git a/host/include/uhd/transport/zero_copy_recv_offload.hpp b/host/include/uhd/transport/zero_copy_recv_offload.hpp index 92aa28073..04878f72d 100644 --- a/host/include/uhd/transport/zero_copy_recv_offload.hpp +++ b/host/include/uhd/transport/zero_copy_recv_offload.hpp @@ -12,13 +12,14 @@ #include <uhd/transport/zero_copy.hpp> #include <boost/shared_ptr.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { /*! * A threaded transport offload that is meant to relieve the main thread of * the responsibility of making receive calls. */ -class UHD_API zero_copy_recv_offload : public virtual zero_copy_if { +class UHD_API zero_copy_recv_offload : public virtual zero_copy_if +{ public: typedef boost::shared_ptr<zero_copy_recv_offload> sptr; @@ -31,10 +32,9 @@ public: * \param transport a shared pointer to the transport interface * \param timeout a general timeout for pushing and pulling on the bounded buffer */ - static sptr make(zero_copy_if::sptr transport, - const double timeout); + static sptr make(zero_copy_if::sptr transport, const double timeout); }; -}} //namespace +}} // namespace uhd::transport #endif /* INCLUDED_ZERO_COPY_OFFLOAD_HPP */ diff --git a/host/include/uhd/types/byte_vector.hpp b/host/include/uhd/types/byte_vector.hpp index 9cf0be88c..64c0911e2 100644 --- a/host/include/uhd/types/byte_vector.hpp +++ b/host/include/uhd/types/byte_vector.hpp @@ -14,22 +14,23 @@ #include <string> #include <vector> -namespace uhd{ +namespace uhd { - //! Byte vector used for I2C data passing and EEPROM parsing. - typedef std::vector<uint8_t> byte_vector_t; +//! Byte vector used for I2C data passing and EEPROM parsing. +typedef std::vector<uint8_t> byte_vector_t; - template<typename RangeSrc, typename RangeDst> UHD_INLINE - void byte_copy(const RangeSrc &src, RangeDst &dst){ - std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); - } +template <typename RangeSrc, typename RangeDst> +UHD_INLINE void byte_copy(const RangeSrc& src, RangeDst& dst) +{ + std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); +} - //! Create a string from a byte vector, terminate when invalid ASCII encountered - UHD_API std::string bytes_to_string(const byte_vector_t &bytes); +//! Create a string from a byte vector, terminate when invalid ASCII encountered +UHD_API std::string bytes_to_string(const byte_vector_t& bytes); - //! Create a byte vector from a string, end at null terminator or max length - UHD_API byte_vector_t string_to_bytes(const std::string &str, size_t max_length); +//! Create a byte vector from a string, end at null terminator or max length +UHD_API byte_vector_t string_to_bytes(const std::string& str, size_t max_length); -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_BYTE_VECTOR_HPP */ diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp index 92b7b7e44..30a754f54 100644 --- a/host/include/uhd/types/clock_config.hpp +++ b/host/include/uhd/types/clock_config.hpp @@ -10,47 +10,48 @@ #include <uhd/config.hpp> -namespace uhd{ - - /*! - * The DEPRECATED Clock configuration settings: - * The source for the 10MHz reference clock. - * The source and polarity for the PPS clock. - * - * Deprecated in favor of set time/clock source calls. - * Its still in this file for the sake of gr-uhd swig. - * - * Use the convenience functions external() and internal(), - * unless you have a special purpose and cannot use them. - */ - struct UHD_API clock_config_t{ - //------ simple usage --------// - - //! A convenience function to create an external clock configuration - static clock_config_t external(void); - - //! A convenience function to create an internal clock configuration - static clock_config_t internal(void); - - //------ advanced usage --------// - enum ref_source_t { - REF_AUTO = int('a'), //automatic (device specific) - REF_INT = int('i'), //internal reference - REF_SMA = int('s'), //external sma port - REF_MIMO = int('m') //reference from mimo cable - } ref_source; - enum pps_source_t { - PPS_INT = int('i'), //there is no internal - PPS_SMA = int('s'), //external sma port - PPS_MIMO = int('m') //time sync from mimo cable - } pps_source; - enum pps_polarity_t { - PPS_NEG = int('n'), //negative edge - PPS_POS = int('p') //positive edge - } pps_polarity; - clock_config_t(void); - }; - -} //namespace uhd +namespace uhd { + +/*! + * The DEPRECATED Clock configuration settings: + * The source for the 10MHz reference clock. + * The source and polarity for the PPS clock. + * + * Deprecated in favor of set time/clock source calls. + * Its still in this file for the sake of gr-uhd swig. + * + * Use the convenience functions external() and internal(), + * unless you have a special purpose and cannot use them. + */ +struct UHD_API clock_config_t +{ + //------ simple usage --------// + + //! A convenience function to create an external clock configuration + static clock_config_t external(void); + + //! A convenience function to create an internal clock configuration + static clock_config_t internal(void); + + //------ advanced usage --------// + enum ref_source_t { + REF_AUTO = int('a'), // automatic (device specific) + REF_INT = int('i'), // internal reference + REF_SMA = int('s'), // external sma port + REF_MIMO = int('m') // reference from mimo cable + } ref_source; + enum pps_source_t { + PPS_INT = int('i'), // there is no internal + PPS_SMA = int('s'), // external sma port + PPS_MIMO = int('m') // time sync from mimo cable + } pps_source; + enum pps_polarity_t { + PPS_NEG = int('n'), // negative edge + PPS_POS = int('p') // positive edge + } pps_polarity; + clock_config_t(void); +}; + +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP */ diff --git a/host/include/uhd/types/component_file.hpp b/host/include/uhd/types/component_file.hpp index 07c009257..905fc067f 100644 --- a/host/include/uhd/types/component_file.hpp +++ b/host/include/uhd/types/component_file.hpp @@ -11,26 +11,27 @@ #include <string> #include <vector> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - /*! Defines a file that can be sent using update_component - * - * \param metadata dictionary of strings that define the metadata - * associated with the file. - * - * Keys must include "id" and "filename", and may include an "md5" hash, - * as well as other, device- or component-specific keys. - * - * \param data the binary data file - * - * Can be the contents of the FPGA image file, for example. - */ - struct component_file_t { - uhd::dict<std::string, std::string> metadata; - std::vector<uint8_t> data; - }; +/*! Defines a file that can be sent using update_component + * + * \param metadata dictionary of strings that define the metadata + * associated with the file. + * + * Keys must include "id" and "filename", and may include an "md5" hash, + * as well as other, device- or component-specific keys. + * + * \param data the binary data file + * + * Can be the contents of the FPGA image file, for example. + */ +struct component_file_t +{ + uhd::dict<std::string, std::string> metadata; + std::vector<uint8_t> data; +}; - typedef std::vector<component_file_t> component_files_t; +typedef std::vector<component_file_t> component_files_t; }} // namespace uhd::usrp diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp index b9d3659c0..93a5d345f 100644 --- a/host/include/uhd/types/device_addr.hpp +++ b/host/include/uhd/types/device_addr.hpp @@ -11,85 +11,87 @@ #include <uhd/config.hpp> #include <uhd/types/dict.hpp> #include <boost/lexical_cast.hpp> +#include <map> #include <stdexcept> -#include <vector> #include <string> -#include <map> +#include <vector> -namespace uhd{ +namespace uhd { +/*! + * Mapping of key/value pairs for locating devices on the system. + * When left empty, the device discovery routines will search + * all available transports on the system (ethernet, usb...). + * + * To narrow down the discovery process to a particular device, + * specify a transport key/value pair specific to your device. + * - Ex, to find a usrp2: my_dev_addr["addr"] = [resolvable_hostname_or_ip] + * + * The device address can also be used to pass arguments into + * the transport layer control to set (for example) buffer sizes. + * + * An arguments string, is a way to represent a device address + * using a single string with delimiter characters. + * - Ex: addr=192.168.10.2 + * - Ex: addr=192.168.10.2, recv_buff_size=1e6 + */ +class UHD_API device_addr_t : public dict<std::string, std::string> +{ +public: /*! - * Mapping of key/value pairs for locating devices on the system. - * When left empty, the device discovery routines will search - * all available transports on the system (ethernet, usb...). - * - * To narrow down the discovery process to a particular device, - * specify a transport key/value pair specific to your device. - * - Ex, to find a usrp2: my_dev_addr["addr"] = [resolvable_hostname_or_ip] - * - * The device address can also be used to pass arguments into - * the transport layer control to set (for example) buffer sizes. - * - * An arguments string, is a way to represent a device address - * using a single string with delimiter characters. - * - Ex: addr=192.168.10.2 - * - Ex: addr=192.168.10.2, recv_buff_size=1e6 + * Create a device address from an args string. + * \param args the arguments string */ - class UHD_API device_addr_t : public dict<std::string, std::string>{ - public: - /*! - * Create a device address from an args string. - * \param args the arguments string - */ - device_addr_t(const std::string &args = ""); + device_addr_t(const std::string& args = ""); - /*! - * Create a device address from a std::map - * \param info the device info map - */ - device_addr_t(const std::map<std::string, std::string> &info); + /*! + * Create a device address from a std::map + * \param info the device info map + */ + device_addr_t(const std::map<std::string, std::string>& info); - /*! - * Convert a device address into a pretty print string. - * \return a printable string representing the device address - */ - std::string to_pp_string(void) const; + /*! + * Convert a device address into a pretty print string. + * \return a printable string representing the device address + */ + std::string to_pp_string(void) const; - /*! - * Convert the device address into an args string. - * The args string contains delimiter symbols. - * \return a string with delimiter markup - */ - std::string to_string(void) const; + /*! + * Convert the device address into an args string. + * The args string contains delimiter symbols. + * \return a string with delimiter markup + */ + std::string to_string(void) const; - /*! - * Lexically cast a parameter to the specified type, - * or use the default value if the key is not found. - * \param key the key as one of the address parameters - * \param def the value to use when key is not present - * \return the casted value as type T or the default - * \throw error when the parameter cannot be casted - */ - template <typename T> T cast(const std::string &key, const T &def) const{ - if (not this->has_key(key)) return def; - try{ - return boost::lexical_cast<T>((*this)[key]); - } - catch(const boost::bad_lexical_cast &){ - throw std::runtime_error("cannot cast " + key + " = " + (*this)[key]); - } + /*! + * Lexically cast a parameter to the specified type, + * or use the default value if the key is not found. + * \param key the key as one of the address parameters + * \param def the value to use when key is not present + * \return the casted value as type T or the default + * \throw error when the parameter cannot be casted + */ + template <typename T> T cast(const std::string& key, const T& def) const + { + if (not this->has_key(key)) + return def; + try { + return boost::lexical_cast<T>((*this)[key]); + } catch (const boost::bad_lexical_cast&) { + throw std::runtime_error("cannot cast " + key + " = " + (*this)[key]); } - }; + } +}; - //! A typedef for a vector of device addresses - typedef std::vector<device_addr_t> device_addrs_t; +//! A typedef for a vector of device addresses +typedef std::vector<device_addr_t> device_addrs_t; - //! Separate an indexed device address into a vector of device addresses - UHD_API device_addrs_t separate_device_addr(const device_addr_t &dev_addr); +//! Separate an indexed device address into a vector of device addresses +UHD_API device_addrs_t separate_device_addr(const device_addr_t& dev_addr); - //! Combine a vector of device addresses into an indexed device address - UHD_API device_addr_t combine_device_addrs(const device_addrs_t &dev_addrs); +//! Combine a vector of device addresses into an indexed device address +UHD_API device_addr_t combine_device_addrs(const device_addrs_t& dev_addrs); -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP */ diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp index 51594e17b..8b7a63c69 100644 --- a/host/include/uhd/types/dict.hpp +++ b/host/include/uhd/types/dict.hpp @@ -9,141 +9,141 @@ #define INCLUDED_UHD_TYPES_DICT_HPP #include <uhd/config.hpp> -#include <vector> #include <list> +#include <vector> + +namespace uhd { + +/*! + * A templated dictionary class with a python-like interface. + */ +template <typename Key, typename Val> class dict +{ +public: + /*! + * Create a new empty dictionary. + */ + dict(void); + + /*! + * Input iterator constructor: + * Makes boost::assign::map_list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template <typename InputIterator> dict(InputIterator first, InputIterator last); + + /*! + * Get the number of elements in this dict. + * \return the number of elements + */ + std::size_t size(void) const; + + /*! + * Get a list of the keys in this dict. + * Key order depends on insertion precedence. + * \return vector of keys + */ + std::vector<Key> keys(void) const; + + /*! + * Get a list of the values in this dict. + * Value order depends on insertion precedence. + * \return vector of values + */ + std::vector<Val> vals(void) const; + + /*! + * Does the dictionary contain this key? + * \param key the key to look for + * \return true if found + */ + bool has_key(const Key& key) const; + + /*! + * Get a value in the dict or default. + * \param key the key to look for + * \param other use if key not found + * \return the value or default + */ + const Val& get(const Key& key, const Val& other) const; + + /*! + * Get a value in the dict or throw. + * \param key the key to look for + * \return the value or default + */ + const Val& get(const Key& key) const; + + /*! + * Set a value in the dict at the key. + * \param key the key to set at + * \param val the value to set + */ + void set(const Key& key, const Val& val); + + /*! + * Get a value for the given key if it exists. + * If the key is not found throw an error. + * \param key the key to look for + * \return the value at the key + * \throw an exception when not found + */ + const Val& operator[](const Key& key) const; -namespace uhd{ + /*! + * Set a value for the given key, however, in reality + * it really returns a reference which can be assigned to. + * \param key the key to set to + * \return a reference to the value + */ + Val& operator[](const Key& key); + + /*! + * Equals operator for the dict type + * \param other the dict being compared to this + * \return whether or not the two dict's are equal + */ + bool operator==(const dict<Key, Val>& other) const; /*! - * A templated dictionary class with a python-like interface. + * Not equal operator for the dict type + * \param other the dict being compared to this + * \return whether or not the two dict's are not equal */ - template <typename Key, typename Val> class dict{ - public: - /*! - * Create a new empty dictionary. - */ - dict(void); - - /*! - * Input iterator constructor: - * Makes boost::assign::map_list_of work. - * \param first the begin iterator - * \param last the end iterator - */ - template <typename InputIterator> - dict(InputIterator first, InputIterator last); - - /*! - * Get the number of elements in this dict. - * \return the number of elements - */ - std::size_t size(void) const; - - /*! - * Get a list of the keys in this dict. - * Key order depends on insertion precedence. - * \return vector of keys - */ - std::vector<Key> keys(void) const; - - /*! - * Get a list of the values in this dict. - * Value order depends on insertion precedence. - * \return vector of values - */ - std::vector<Val> vals(void) const; - - /*! - * Does the dictionary contain this key? - * \param key the key to look for - * \return true if found - */ - bool has_key(const Key &key) const; - - /*! - * Get a value in the dict or default. - * \param key the key to look for - * \param other use if key not found - * \return the value or default - */ - const Val &get(const Key &key, const Val &other) const; - - /*! - * Get a value in the dict or throw. - * \param key the key to look for - * \return the value or default - */ - const Val &get(const Key &key) const; - - /*! - * Set a value in the dict at the key. - * \param key the key to set at - * \param val the value to set - */ - void set(const Key &key, const Val &val); - - /*! - * Get a value for the given key if it exists. - * If the key is not found throw an error. - * \param key the key to look for - * \return the value at the key - * \throw an exception when not found - */ - const Val &operator[](const Key &key) const; - - /*! - * Set a value for the given key, however, in reality - * it really returns a reference which can be assigned to. - * \param key the key to set to - * \return a reference to the value - */ - Val &operator[](const Key &key); - - /*! - * Equals operator for the dict type - * \param other the dict being compared to this - * \return whether or not the two dict's are equal - */ - bool operator==(const dict<Key, Val> &other) const; - - /*! - * Not equal operator for the dict type - * \param other the dict being compared to this - * \return whether or not the two dict's are not equal - */ - bool operator!=(const dict<Key, Val> &other) const; - - /*! - * Pop an item out of the dictionary. - * \param key the item key - * \return the value of the item - * \throw an exception when not found - */ - Val pop(const Key &key); - - /*! Update this dictionary with values from another. - * - * Basically, this copies all the key/value pairs from \p new_dict - * into this dict. When the key is already present in the current - * dict, it either overwrites the current value (if \p fail_on_conflict - * is false) or it throws (if \p fail_on_conflict is true *and* the - * values differ). - * - * With the exception of \p fail_on_conflict, this behaves analogously - * to Python's dict.update() method. - * - * \param new_dict The arguments to copy. - * \param fail_on_conflict If true, throws. - * \throws uhd::value_error - */ - void update(const dict<Key, Val> &new_dict, bool fail_on_conflict=true); - - private: - typedef std::pair<Key, Val> pair_t; - std::list<pair_t> _map; //private container - }; - -} //namespace uhd + bool operator!=(const dict<Key, Val>& other) const; + + /*! + * Pop an item out of the dictionary. + * \param key the item key + * \return the value of the item + * \throw an exception when not found + */ + Val pop(const Key& key); + + /*! Update this dictionary with values from another. + * + * Basically, this copies all the key/value pairs from \p new_dict + * into this dict. When the key is already present in the current + * dict, it either overwrites the current value (if \p fail_on_conflict + * is false) or it throws (if \p fail_on_conflict is true *and* the + * values differ). + * + * With the exception of \p fail_on_conflict, this behaves analogously + * to Python's dict.update() method. + * + * \param new_dict The arguments to copy. + * \param fail_on_conflict If true, throws. + * \throws uhd::value_error + */ + void update(const dict<Key, Val>& new_dict, bool fail_on_conflict = true); + +private: + typedef std::pair<Key, Val> pair_t; + std::list<pair_t> _map; // private container +}; + +} // namespace uhd #include <uhd/types/dict.ipp> diff --git a/host/include/uhd/types/direction.hpp b/host/include/uhd/types/direction.hpp index 79d942bd6..73ef0c07f 100644 --- a/host/include/uhd/types/direction.hpp +++ b/host/include/uhd/types/direction.hpp @@ -10,15 +10,15 @@ namespace uhd { - enum direction_t { - //! Receive - RX_DIRECTION, - //! Transmit - TX_DIRECTION, - //! Duplex - DX_DIRECTION - }; +enum direction_t { + //! Receive + RX_DIRECTION, + //! Transmit + TX_DIRECTION, + //! Duplex + DX_DIRECTION +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_DIRECTION_HPP */ diff --git a/host/include/uhd/types/eeprom.hpp b/host/include/uhd/types/eeprom.hpp index a61fbf211..d2b29fe6b 100644 --- a/host/include/uhd/types/eeprom.hpp +++ b/host/include/uhd/types/eeprom.hpp @@ -13,7 +13,7 @@ namespace uhd { - typedef std::map<std::string, std::vector<uint8_t>> eeprom_map_t; +typedef std::map<std::string, std::vector<uint8_t> > eeprom_map_t; } /* namespace uhd */ diff --git a/host/include/uhd/types/endianness.hpp b/host/include/uhd/types/endianness.hpp index 74b8f43e9..a14bfcd23 100644 --- a/host/include/uhd/types/endianness.hpp +++ b/host/include/uhd/types/endianness.hpp @@ -10,13 +10,10 @@ #include <uhd/config.hpp> -namespace uhd{ +namespace uhd { - enum endianness_t { - ENDIANNESS_BIG, - ENDIANNESS_LITTLE - }; +enum endianness_t { ENDIANNESS_BIG, ENDIANNESS_LITTLE }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_ENDIANNESS_HPP */ diff --git a/host/include/uhd/types/filters.hpp b/host/include/uhd/types/filters.hpp index 9879774cc..ff72dd5e3 100644 --- a/host/include/uhd/types/filters.hpp +++ b/host/include/uhd/types/filters.hpp @@ -10,267 +10,249 @@ #include <uhd/config.hpp> #include <uhd/utils/log.hpp> - #include <stdint.h> -#include <boost/shared_ptr.hpp> #include <boost/scoped_array.hpp> -#include <string> -#include <vector> +#include <boost/shared_ptr.hpp> #include <iostream> #include <ostream> #include <sstream> +#include <string> +#include <vector> -namespace uhd{ - - class UHD_API filter_info_base - { - public: - typedef boost::shared_ptr<filter_info_base> sptr; - enum filter_type - { - ANALOG_LOW_PASS, - ANALOG_BAND_PASS, - DIGITAL_I16, - DIGITAL_FIR_I16 - }; - - filter_info_base( - filter_type type, - bool bypass, - size_t position_index - ): - _type(type), _bypass(bypass), - _position_index(position_index) - { - //NOP - } - - UHD_INLINE virtual bool is_bypassed() - { - return _bypass; - } - - UHD_INLINE filter_type get_type() - { - return _type; - } - - virtual ~filter_info_base() - { - //NOP - } - - virtual std::string to_pp_string(); - - protected: - filter_type _type; - bool _bypass; - size_t _position_index; - - }; +namespace uhd { - UHD_API std::ostream& operator<<(std::ostream& os, filter_info_base& f); +class UHD_API filter_info_base +{ +public: + typedef boost::shared_ptr<filter_info_base> sptr; + enum filter_type { ANALOG_LOW_PASS, ANALOG_BAND_PASS, DIGITAL_I16, DIGITAL_FIR_I16 }; - class UHD_API analog_filter_base : public filter_info_base + filter_info_base(filter_type type, bool bypass, size_t position_index) + : _type(type), _bypass(bypass), _position_index(position_index) { - std::string _analog_type; - public: - typedef boost::shared_ptr<analog_filter_base> sptr; - analog_filter_base( - filter_type type, - bool bypass, - size_t position_index, - const std::string& analog_type - ): - filter_info_base(type, bypass, position_index), - _analog_type(analog_type) - { - //NOP - } + // NOP + } - UHD_INLINE const std::string& get_analog_type() - { - return _analog_type; - } - - virtual std::string to_pp_string(); - }; + UHD_INLINE virtual bool is_bypassed() + { + return _bypass; + } - class UHD_API analog_filter_lp : public analog_filter_base + UHD_INLINE filter_type get_type() { - double _cutoff; - double _rolloff; - - public: - typedef boost::shared_ptr<analog_filter_lp> sptr; - analog_filter_lp( - filter_type type, - bool bypass, - size_t position_index, - const std::string& analog_type, - double cutoff, - double rolloff - ): - analog_filter_base(type, bypass, position_index, analog_type), - _cutoff(cutoff), - _rolloff(rolloff) - { - //NOP - } + return _type; + } - UHD_INLINE double get_cutoff() - { - return _cutoff; - } + virtual ~filter_info_base() + { + // NOP + } + + virtual std::string to_pp_string(); + +protected: + filter_type _type; + bool _bypass; + size_t _position_index; +}; + +UHD_API std::ostream& operator<<(std::ostream& os, filter_info_base& f); + +class UHD_API analog_filter_base : public filter_info_base +{ + std::string _analog_type; + +public: + typedef boost::shared_ptr<analog_filter_base> sptr; + analog_filter_base(filter_type type, + bool bypass, + size_t position_index, + const std::string& analog_type) + : filter_info_base(type, bypass, position_index), _analog_type(analog_type) + { + // NOP + } - UHD_INLINE double get_rolloff() - { - return _rolloff; - } + UHD_INLINE const std::string& get_analog_type() + { + return _analog_type; + } + + virtual std::string to_pp_string(); +}; + +class UHD_API analog_filter_lp : public analog_filter_base +{ + double _cutoff; + double _rolloff; + +public: + typedef boost::shared_ptr<analog_filter_lp> sptr; + analog_filter_lp(filter_type type, + bool bypass, + size_t position_index, + const std::string& analog_type, + double cutoff, + double rolloff) + : analog_filter_base(type, bypass, position_index, analog_type) + , _cutoff(cutoff) + , _rolloff(rolloff) + { + // NOP + } - UHD_INLINE void set_cutoff(const double cutoff) - { - _cutoff = cutoff; - } + UHD_INLINE double get_cutoff() + { + return _cutoff; + } - virtual std::string to_pp_string(); - }; + UHD_INLINE double get_rolloff() + { + return _rolloff; + } - template<typename tap_t> - class UHD_API digital_filter_base : public filter_info_base + UHD_INLINE void set_cutoff(const double cutoff) { - protected: - double _rate; - uint32_t _interpolation; - uint32_t _decimation; - tap_t _tap_full_scale; - uint32_t _max_num_taps; - std::vector<tap_t> _taps; - - public: - typedef boost::shared_ptr<digital_filter_base> sptr; - digital_filter_base( - filter_type type, - bool bypass, - size_t position_index, - double rate, - size_t interpolation, - size_t decimation, - double tap_full_scale, - size_t max_num_taps, - const std::vector<tap_t>& taps - ): - filter_info_base(type, bypass, position_index), - _rate(rate), - _interpolation(interpolation), - _decimation(decimation), - _tap_full_scale(tap_full_scale), - _max_num_taps(max_num_taps), - _taps(taps) - { - //NOP - } + _cutoff = cutoff; + } + + virtual std::string to_pp_string(); +}; + +template <typename tap_t> class UHD_API digital_filter_base : public filter_info_base +{ +protected: + double _rate; + uint32_t _interpolation; + uint32_t _decimation; + tap_t _tap_full_scale; + uint32_t _max_num_taps; + std::vector<tap_t> _taps; + +public: + typedef boost::shared_ptr<digital_filter_base> sptr; + digital_filter_base(filter_type type, + bool bypass, + size_t position_index, + double rate, + size_t interpolation, + size_t decimation, + double tap_full_scale, + size_t max_num_taps, + const std::vector<tap_t>& taps) + : filter_info_base(type, bypass, position_index) + , _rate(rate) + , _interpolation(interpolation) + , _decimation(decimation) + , _tap_full_scale(tap_full_scale) + , _max_num_taps(max_num_taps) + , _taps(taps) + { + // NOP + } - UHD_INLINE double get_output_rate() - { - return (_bypass ? _rate : (_rate / _decimation * _interpolation)); - } + UHD_INLINE double get_output_rate() + { + return (_bypass ? _rate : (_rate / _decimation * _interpolation)); + } - UHD_INLINE double get_input_rate() - { - return _rate; - } + UHD_INLINE double get_input_rate() + { + return _rate; + } - UHD_INLINE double get_interpolation() - { - return _interpolation; - } + UHD_INLINE double get_interpolation() + { + return _interpolation; + } - UHD_INLINE double get_decimation() - { - return _decimation; - } + UHD_INLINE double get_decimation() + { + return _decimation; + } - UHD_INLINE double get_tap_full_scale() - { - return _tap_full_scale; - } + UHD_INLINE double get_tap_full_scale() + { + return _tap_full_scale; + } - UHD_INLINE std::vector<tap_t>& get_taps() - { - return _taps; - } + UHD_INLINE std::vector<tap_t>& get_taps() + { + return _taps; + } - virtual std::string to_pp_string() - { - std::ostringstream os; - os<<filter_info_base::to_pp_string()<< - "\t[digital_filter_base]"<<std::endl<< - "\tinput rate: "<<_rate<<std::endl<< - "\tinterpolation: "<<_interpolation<<std::endl<< - "\tdecimation: "<<_decimation<<std::endl<< - "\tfull-scale: "<<_tap_full_scale<<std::endl<< - "\tmax num taps: "<<_max_num_taps<<std::endl<< - "\ttaps: "<<std::endl; - - os<<"\t\t"; - for(size_t i = 0; i < _taps.size(); i++) - { - os<<"(tap "<<i<<": "<<_taps[i]<<")"; - if( ((i%10) == 0) && (i != 0)) - { - os<<std::endl<<"\t\t"; - } + virtual std::string to_pp_string() + { + std::ostringstream os; + os << filter_info_base::to_pp_string() << "\t[digital_filter_base]" << std::endl + << "\tinput rate: " << _rate << std::endl + << "\tinterpolation: " << _interpolation << std::endl + << "\tdecimation: " << _decimation << std::endl + << "\tfull-scale: " << _tap_full_scale << std::endl + << "\tmax num taps: " << _max_num_taps << std::endl + << "\ttaps: " << std::endl; + + os << "\t\t"; + for (size_t i = 0; i < _taps.size(); i++) { + os << "(tap " << i << ": " << _taps[i] << ")"; + if (((i % 10) == 0) && (i != 0)) { + os << std::endl << "\t\t"; } - os<<std::endl; - return std::string(os.str()); } - - }; - - template<typename tap_t> - class UHD_API digital_filter_fir : public digital_filter_base<tap_t> + os << std::endl; + return std::string(os.str()); + } +}; + +template <typename tap_t> +class UHD_API digital_filter_fir : public digital_filter_base<tap_t> +{ +public: + typedef boost::shared_ptr<digital_filter_fir<tap_t> > sptr; + + digital_filter_fir(filter_info_base::filter_type type, + bool bypass, + size_t position_index, + double rate, + size_t interpolation, + size_t decimation, + size_t tap_bit_width, + size_t max_num_taps, + const std::vector<tap_t>& taps) + : digital_filter_base<tap_t>(type, + bypass, + position_index, + rate, + interpolation, + decimation, + tap_bit_width, + max_num_taps, + taps) { - public: - typedef boost::shared_ptr<digital_filter_fir<tap_t> > sptr; - - digital_filter_fir( - filter_info_base::filter_type type, - bool bypass, size_t position_index, - double rate, - size_t interpolation, - size_t decimation, - size_t tap_bit_width, - size_t max_num_taps, - const std::vector<tap_t>& taps - ): - digital_filter_base<tap_t>(type, bypass, position_index, rate, interpolation, decimation, tap_bit_width, max_num_taps, taps) - { - //NOP - } + // NOP + } - void set_taps(const std::vector<tap_t>& taps) - { - std::size_t num_taps = taps.size(); - if(num_taps < this->_max_num_taps){ - UHD_LOGGER_WARNING("FILTERS") << "digital_filter_fir::set_taps not enough coefficients. Appending zeros"; - std::vector<tap_t> coeffs; - for (size_t i = 0; i < this->_max_num_taps; i++) - { - if(i < num_taps) - { - coeffs.push_back(taps[i]); - } else { - coeffs.push_back(0); - } + void set_taps(const std::vector<tap_t>& taps) + { + std::size_t num_taps = taps.size(); + if (num_taps < this->_max_num_taps) { + UHD_LOGGER_WARNING("FILTERS") << "digital_filter_fir::set_taps not enough " + "coefficients. Appending zeros"; + std::vector<tap_t> coeffs; + for (size_t i = 0; i < this->_max_num_taps; i++) { + if (i < num_taps) { + coeffs.push_back(taps[i]); + } else { + coeffs.push_back(0); } - this->_taps = coeffs; - } else { - this->_taps = taps; } + this->_taps = coeffs; + } else { + this->_taps = taps; } - }; + } +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_FILTERS_HPP */ diff --git a/host/include/uhd/types/io_type.hpp b/host/include/uhd/types/io_type.hpp index 3effe5cec..01e10142c 100644 --- a/host/include/uhd/types/io_type.hpp +++ b/host/include/uhd/types/io_type.hpp @@ -10,60 +10,59 @@ #include <uhd/config.hpp> -namespace uhd{ +namespace uhd { +/*! + * The DEPRECATED Input/Output configuration struct: + * Used to specify the IO type with device send/recv. + * + * Deprecated in favor of streamer interface. + * Its still in this file for the sake of gr-uhd swig. + */ +class UHD_API io_type_t +{ +public: /*! - * The DEPRECATED Input/Output configuration struct: - * Used to specify the IO type with device send/recv. - * - * Deprecated in favor of streamer interface. - * Its still in this file for the sake of gr-uhd swig. + * Built in IO types known to the system. */ - class UHD_API io_type_t{ - public: - - /*! - * Built in IO types known to the system. - */ - enum tid_t{ - //! Custom type (technically unsupported by implementation) - CUSTOM_TYPE = int('?'), - //! Complex floating point (64-bit floats) range [-1.0, +1.0] - COMPLEX_FLOAT64 = int('d'), - //! Complex floating point (32-bit floats) range [-1.0, +1.0] - COMPLEX_FLOAT32 = int('f'), - //! Complex signed integer (16-bit integers) range [-32768, +32767] - COMPLEX_INT16 = int('s'), - //! Complex signed integer (8-bit integers) range [-128, 127] - COMPLEX_INT8 = int('b') - }; - - /*! - * The size of this io type in bytes. - */ - const size_t size; + enum tid_t { + //! Custom type (technically unsupported by implementation) + CUSTOM_TYPE = int('?'), + //! Complex floating point (64-bit floats) range [-1.0, +1.0] + COMPLEX_FLOAT64 = int('d'), + //! Complex floating point (32-bit floats) range [-1.0, +1.0] + COMPLEX_FLOAT32 = int('f'), + //! Complex signed integer (16-bit integers) range [-32768, +32767] + COMPLEX_INT16 = int('s'), + //! Complex signed integer (8-bit integers) range [-128, 127] + COMPLEX_INT8 = int('b') + }; - /*! - * The type id of this io type. - * Good for using with switch statements. - */ - const tid_t tid; + /*! + * The size of this io type in bytes. + */ + const size_t size; - /*! - * Create an io type from a built-in type id. - * \param tid a type id known to the system - */ - io_type_t(tid_t tid); + /*! + * The type id of this io type. + * Good for using with switch statements. + */ + const tid_t tid; - /*! - * Create an io type from attributes. - * The tid will be set to custom. - * \param size the size in bytes - */ - io_type_t(size_t size); + /*! + * Create an io type from a built-in type id. + * \param tid a type id known to the system + */ + io_type_t(tid_t tid); - }; + /*! + * Create an io type from attributes. + * The tid will be set to custom. + * \param size the size in bytes + */ + io_type_t(size_t size); +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_IO_TYPE_HPP */ diff --git a/host/include/uhd/types/mac_addr.hpp b/host/include/uhd/types/mac_addr.hpp index ff119c5de..316c5890c 100644 --- a/host/include/uhd/types/mac_addr.hpp +++ b/host/include/uhd/types/mac_addr.hpp @@ -12,45 +12,46 @@ #include <uhd/types/serial.hpp> #include <string> -namespace uhd{ +namespace uhd { + +/*! + * Wrapper for an ethernet mac address. + * Provides conversion between string and binary formats. + */ +class UHD_API mac_addr_t +{ +public: + /*! + * Create a mac address a byte array. + * \param bytes a vector of bytes + * \return a new mac address + */ + static mac_addr_t from_bytes(const byte_vector_t& bytes); + + /*! + * Create a mac address from a string. + * \param mac_addr_str the string with delimiters + * \return a new mac address + */ + static mac_addr_t from_string(const std::string& mac_addr_str); /*! - * Wrapper for an ethernet mac address. - * Provides conversion between string and binary formats. - */ - class UHD_API mac_addr_t{ - public: - /*! - * Create a mac address a byte array. - * \param bytes a vector of bytes - * \return a new mac address - */ - static mac_addr_t from_bytes(const byte_vector_t &bytes); - - /*! - * Create a mac address from a string. - * \param mac_addr_str the string with delimiters - * \return a new mac address - */ - static mac_addr_t from_string(const std::string &mac_addr_str); - - /*! - * Get the byte representation of the mac address. - * \return a vector of bytes - */ - byte_vector_t to_bytes(void) const; - - /*! - * Get the string representation of this mac address. - * \return a string with delimiters - */ - std::string to_string(void) const; - - private: - mac_addr_t(const byte_vector_t &bytes); //private constructor - const byte_vector_t _bytes; //internal representation - }; - -} //namespace uhd + * Get the byte representation of the mac address. + * \return a vector of bytes + */ + byte_vector_t to_bytes(void) const; + + /*! + * Get the string representation of this mac address. + * \return a string with delimiters + */ + std::string to_string(void) const; + +private: + mac_addr_t(const byte_vector_t& bytes); // private constructor + const byte_vector_t _bytes; // internal representation +}; + +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_MAC_ADDR_HPP */ diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index b46eb0a89..a29cae93c 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -13,186 +13,190 @@ #include <stdint.h> #include <string> -namespace uhd{ +namespace uhd { + +/*! + * RX metadata structure for describing sent IF data. + * Includes time specification, fragmentation flags, burst flags, and error codes. + * The receive routines will convert IF data headers into metadata. + */ +struct UHD_API rx_metadata_t +{ + //! Default constructor. + rx_metadata_t() + { + reset(); + } + + //! Reset values. + void reset() + { + has_time_spec = false; + time_spec = time_spec_t(0.0); + more_fragments = false; + fragment_offset = 0; + start_of_burst = false; + end_of_burst = false; + error_code = ERROR_CODE_NONE; + out_of_sequence = false; + } + + //! Has time specification? + bool has_time_spec; + + //! Time of the first sample. + time_spec_t time_spec; /*! - * RX metadata structure for describing sent IF data. - * Includes time specification, fragmentation flags, burst flags, and error codes. - * The receive routines will convert IF data headers into metadata. + * Fragmentation flag: + * Similar to IPv4 fragmentation: + * http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly More fragments is + * true when the input buffer has insufficient size to fit an entire received packet. + * More fragments will be false for the last fragment. */ - struct UHD_API rx_metadata_t{ - - //! Default constructor. - rx_metadata_t() - { - reset(); - } - - //! Reset values. - void reset() - { - has_time_spec = false; - time_spec = time_spec_t(0.0); - more_fragments = false; - fragment_offset = 0; - start_of_burst = false; - end_of_burst = false; - error_code = ERROR_CODE_NONE; - out_of_sequence = false; - } - - //! Has time specification? - bool has_time_spec; - - //! Time of the first sample. - time_spec_t time_spec; + bool more_fragments; - /*! - * Fragmentation flag: - * Similar to IPv4 fragmentation: http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly - * More fragments is true when the input buffer has insufficient size to fit - * an entire received packet. More fragments will be false for the last fragment. - */ - bool more_fragments; - - /*! - * Fragmentation offset: - * The fragment offset is the sample number at the start of the receive buffer. - * For non-fragmented receives, the fragment offset should always be zero. - */ - size_t fragment_offset; + /*! + * Fragmentation offset: + * The fragment offset is the sample number at the start of the receive buffer. + * For non-fragmented receives, the fragment offset should always be zero. + */ + size_t fragment_offset; - //! Start of burst will be true for the first packet in the chain. - bool start_of_burst; + //! Start of burst will be true for the first packet in the chain. + bool start_of_burst; - //! End of burst will be true for the last packet in the chain. - bool end_of_burst; - - /*! - * The error condition on a receive call. - * - * Note: When an overrun occurs in continuous streaming mode, - * the device will continue to send samples to the host. - * For other streaming modes, streaming will discontinue - * until the user issues a new stream command. - * - * The metadata fields have meaning for the following error codes: - * - none - * - late command - * - broken chain - * - overflow - */ - enum error_code_t { - //! No error associated with this metadata. - ERROR_CODE_NONE = 0x0, - //! No packet received, implementation timed-out. - ERROR_CODE_TIMEOUT = 0x1, - //! A stream command was issued in the past. - ERROR_CODE_LATE_COMMAND = 0x2, - //! Expected another stream command. - ERROR_CODE_BROKEN_CHAIN = 0x4, - /*! - * An internal receive buffer has filled or a sequence error has been detected. - * So, why is this overloaded? Simple: legacy support. It would have been much cleaner - * to create a separate error code for a sequence error, but that would have broken - * legacy applications. So, the out_of_sequence flag was added to differentiate between - * the two error cases. In either case, data is missing between this time_spec and the - * and the time_spec of the next successful receive. - */ - ERROR_CODE_OVERFLOW = 0x8, - //! Multi-channel alignment failed. - ERROR_CODE_ALIGNMENT = 0xc, - //! The packet could not be parsed. - ERROR_CODE_BAD_PACKET = 0xf - } error_code; - - //! Out of sequence. The transport has either dropped a packet or received data out of order. - bool out_of_sequence; + //! End of burst will be true for the last packet in the chain. + bool end_of_burst; + /*! + * The error condition on a receive call. + * + * Note: When an overrun occurs in continuous streaming mode, + * the device will continue to send samples to the host. + * For other streaming modes, streaming will discontinue + * until the user issues a new stream command. + * + * The metadata fields have meaning for the following error codes: + * - none + * - late command + * - broken chain + * - overflow + */ + enum error_code_t { + //! No error associated with this metadata. + ERROR_CODE_NONE = 0x0, + //! No packet received, implementation timed-out. + ERROR_CODE_TIMEOUT = 0x1, + //! A stream command was issued in the past. + ERROR_CODE_LATE_COMMAND = 0x2, + //! Expected another stream command. + ERROR_CODE_BROKEN_CHAIN = 0x4, /*! - * Convert a rx_metadata_t into a pretty print string. - * - * \param compact Set to false for a more verbose output. - * \return a printable string representing the metadata. + * An internal receive buffer has filled or a sequence error has been detected. + * So, why is this overloaded? Simple: legacy support. It would have been much + * cleaner to create a separate error code for a sequence error, but that would + * have broken legacy applications. So, the out_of_sequence flag was added to + * differentiate between the two error cases. In either case, data is missing + * between this time_spec and the and the time_spec of the next successful + * receive. */ - std::string to_pp_string(bool compact=true) const; + ERROR_CODE_OVERFLOW = 0x8, + //! Multi-channel alignment failed. + ERROR_CODE_ALIGNMENT = 0xc, + //! The packet could not be parsed. + ERROR_CODE_BAD_PACKET = 0xf + } error_code; - /*! - * Similar to C's strerror() function, creates a std::string describing the error code. - * \return a printable string representing the error. - */ - std::string strerror(void) const; - }; + //! Out of sequence. The transport has either dropped a packet or received data out + //! of order. + bool out_of_sequence; /*! - * TX metadata structure for describing received IF data. - * Includes time specification, and start and stop burst flags. - * The send routines will convert the metadata to IF data headers. + * Convert a rx_metadata_t into a pretty print string. + * + * \param compact Set to false for a more verbose output. + * \return a printable string representing the metadata. */ - struct UHD_API tx_metadata_t{ - /*! - * Has time specification? - * - Set false to send immediately. - * - Set true to send at the time specified by time spec. - */ - bool has_time_spec; + std::string to_pp_string(bool compact = true) const; - //! When to send the first sample. - time_spec_t time_spec; + /*! + * Similar to C's strerror() function, creates a std::string describing the error + * code. \return a printable string representing the error. + */ + std::string strerror(void) const; +}; + +/*! + * TX metadata structure for describing received IF data. + * Includes time specification, and start and stop burst flags. + * The send routines will convert the metadata to IF data headers. + */ +struct UHD_API tx_metadata_t +{ + /*! + * Has time specification? + * - Set false to send immediately. + * - Set true to send at the time specified by time spec. + */ + bool has_time_spec; - //! Set start of burst to true for the first packet in the chain. - bool start_of_burst; + //! When to send the first sample. + time_spec_t time_spec; - //! Set end of burst to true for the last packet in the chain. - bool end_of_burst; + //! Set start of burst to true for the first packet in the chain. + bool start_of_burst; - /*! - * The default constructor: - * Sets the fields to default values (flags set to false). - */ - tx_metadata_t(void); - }; + //! Set end of burst to true for the last packet in the chain. + bool end_of_burst; /*! - * Async metadata structure for describing transmit related events. + * The default constructor: + * Sets the fields to default values (flags set to false). */ - struct UHD_API async_metadata_t{ - //! The channel number in a mimo configuration - size_t channel; + tx_metadata_t(void); +}; - //! Has time specification? - bool has_time_spec; +/*! + * Async metadata structure for describing transmit related events. + */ +struct UHD_API async_metadata_t +{ + //! The channel number in a mimo configuration + size_t channel; - //! When the async event occurred. - time_spec_t time_spec; + //! Has time specification? + bool has_time_spec; - /*! - * The type of event for a receive async message call. - */ - enum event_code_t { - //! A burst was successfully transmitted. - EVENT_CODE_BURST_ACK = 0x1, - //! An internal send buffer has emptied. - EVENT_CODE_UNDERFLOW = 0x2, - //! Packet loss between host and device. - EVENT_CODE_SEQ_ERROR = 0x4, - //! Packet had time that was late. - EVENT_CODE_TIME_ERROR = 0x8, - //! Underflow occurred inside a packet. - EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10, - //! Packet loss within a burst. - EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20, - //! Some kind of custom user payload - EVENT_CODE_USER_PAYLOAD = 0x40 - } event_code; + //! When the async event occurred. + time_spec_t time_spec; - /*! - * A special payload populated by custom FPGA fabric. - */ - uint32_t user_payload[4]; + /*! + * The type of event for a receive async message call. + */ + enum event_code_t { + //! A burst was successfully transmitted. + EVENT_CODE_BURST_ACK = 0x1, + //! An internal send buffer has emptied. + EVENT_CODE_UNDERFLOW = 0x2, + //! Packet loss between host and device. + EVENT_CODE_SEQ_ERROR = 0x4, + //! Packet had time that was late. + EVENT_CODE_TIME_ERROR = 0x8, + //! Underflow occurred inside a packet. + EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10, + //! Packet loss within a burst. + EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20, + //! Some kind of custom user payload + EVENT_CODE_USER_PAYLOAD = 0x40 + } event_code; - }; + /*! + * A special payload populated by custom FPGA fabric. + */ + uint32_t user_payload[4]; +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_METADATA_HPP */ diff --git a/host/include/uhd/types/otw_type.hpp b/host/include/uhd/types/otw_type.hpp index 6dc634fc8..ff761cc55 100644 --- a/host/include/uhd/types/otw_type.hpp +++ b/host/include/uhd/types/otw_type.hpp @@ -1,2 +1,2 @@ -//The OTW type API has been deprecated in favor of the streamer interface +// The OTW type API has been deprecated in favor of the streamer interface #include <uhd/deprecated.hpp> diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index 862b5ba8a..982fdae98 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -12,104 +12,106 @@ #include <string> #include <vector> -namespace uhd{ +namespace uhd { + +/*! + * A range object describes a set of discrete values of the form: + * y = start + step*n, where n is an integer between 0 and (stop - start)/step + */ +class UHD_API range_t +{ +public: + /*! + * Create a range from a single value. + * The step size will be taken as zero. + * \param value the only possible value in this range + */ + range_t(double value = 0); /*! - * A range object describes a set of discrete values of the form: - * y = start + step*n, where n is an integer between 0 and (stop - start)/step + * Create a range from a full set of values. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range */ - class UHD_API range_t{ - public: + range_t(double start, double stop, double step = 0); - /*! - * Create a range from a single value. - * The step size will be taken as zero. - * \param value the only possible value in this range - */ - range_t(double value = 0); + //! Get the start value for this range. + double start(void) const; - /*! - * Create a range from a full set of values. - * A step size of zero implies infinite precision. - * \param start the minimum value for this range - * \param stop the maximum value for this range - * \param step the step size for this range - */ - range_t(double start, double stop, double step = 0); + //! Get the stop value for this range. + double stop(void) const; - //! Get the start value for this range. - double start(void) const; + //! Get the step value for this range. + double step(void) const; - //! Get the stop value for this range. - double stop(void) const; + //! Convert this range to a printable string + const std::string to_pp_string(void) const; - //! Get the step value for this range. - double step(void) const; + //! Equality operator + bool operator==(const range_t& other) const; - //! Convert this range to a printable string - const std::string to_pp_string(void) const; + //! Inequality operator + bool operator!=(const range_t& other) const; - //! Equality operator - bool operator==(const range_t &other) const; +private: + double _start, _stop, _step; +}; - //! Inequality operator - bool operator!=(const range_t &other) const; +/*! + * A meta-range object holds a list of individual ranges. + */ +struct UHD_API meta_range_t : std::vector<range_t> +{ + //! A default constructor for an empty meta-range + meta_range_t(void); - private: double _start, _stop, _step; - }; + /*! + * Input iterator constructor: + * Makes boost::assign::list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template <typename InputIterator> + meta_range_t(InputIterator first, InputIterator last) + : std::vector<range_t>(first, last) + { /* NOP */ + } /*! - * A meta-range object holds a list of individual ranges. + * A convenience constructor for a single range. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range */ - struct UHD_API meta_range_t : std::vector<range_t>{ - - //! A default constructor for an empty meta-range - meta_range_t(void); - - /*! - * Input iterator constructor: - * Makes boost::assign::list_of work. - * \param first the begin iterator - * \param last the end iterator - */ - template <typename InputIterator> - meta_range_t(InputIterator first, InputIterator last): - std::vector<range_t>(first, last){ /* NOP */ } - - /*! - * A convenience constructor for a single range. - * A step size of zero implies infinite precision. - * \param start the minimum value for this range - * \param stop the maximum value for this range - * \param step the step size for this range - */ - meta_range_t(double start, double stop, double step = 0); - - //! Get the overall start value for this meta-range. - double start(void) const; - - //! Get the overall stop value for this meta-range. - double stop(void) const; - - //! Get the overall step value for this meta-range. - double step(void) const; - - /*! - * Clip the target value to a possible range value. - * \param value the value to clip to this range - * \param clip_step if true, clip to steps as well - * \return a value that is in one of the ranges - */ - double clip(double value, bool clip_step = false) const; - - //! Convert this meta-range to a printable string - const std::string to_pp_string(void) const; - - }; - - typedef meta_range_t gain_range_t; - typedef meta_range_t freq_range_t; - -} //namespace uhd + meta_range_t(double start, double stop, double step = 0); + + //! Get the overall start value for this meta-range. + double start(void) const; + + //! Get the overall stop value for this meta-range. + double stop(void) const; + + //! Get the overall step value for this meta-range. + double step(void) const; + + /*! + * Clip the target value to a possible range value. + * \param value the value to clip to this range + * \param clip_step if true, clip to steps as well + * \return a value that is in one of the ranges + */ + double clip(double value, bool clip_step = false) const; + + //! Convert this meta-range to a printable string + const std::string to_pp_string(void) const; +}; + +typedef meta_range_t gain_range_t; +typedef meta_range_t freq_range_t; + +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_RANGES_HPP */ diff --git a/host/include/uhd/types/ref_vector.hpp b/host/include/uhd/types/ref_vector.hpp index 6cbc5edd9..2a1fc0aad 100644 --- a/host/include/uhd/types/ref_vector.hpp +++ b/host/include/uhd/types/ref_vector.hpp @@ -11,22 +11,23 @@ #include <uhd/config.hpp> #include <cstddef> -namespace uhd{ +namespace uhd { /*! * Reference vector: * - Provides a std::vector-like interface for an array. * - Statically sized, and does not manage the memory. */ -template <typename T> class UHD_API ref_vector{ +template <typename T> class UHD_API ref_vector +{ public: /*! * Create a reference vector of size 1 from a pointer. * Therefore: rv[0] == ptr and rv.size() == 1 * \param ptr a pointer to a chunk of memory */ - template <typename Ptr> ref_vector(Ptr *ptr): - _ptr(T(ptr)), _mem(_mem_t(&_ptr)), _size(1) + template <typename Ptr> + ref_vector(Ptr* ptr) : _ptr(T(ptr)), _mem(_mem_t(&_ptr)), _size(1) { /* NOP */ } @@ -36,8 +37,9 @@ public: * Therefore: rv[n] == vec[n] and rv.size() == vec.size() * \param vec a const reference to an std::vector */ - template <typename Vector> ref_vector(const Vector &vec): - _ptr(T()), _mem(_mem_t(&vec.front())), _size(vec.size()) + template <typename Vector> + ref_vector(const Vector& vec) + : _ptr(T()), _mem(_mem_t(&vec.front())), _size(vec.size()) { /* NOP */ } @@ -48,29 +50,30 @@ public: * \param mem a pointer to an array of pointers * \param len the length of the array of pointers */ - ref_vector(const T *mem, size_t len): - _ptr(T()), _mem(_mem_t(mem)), _size(len) + ref_vector(const T* mem, size_t len) : _ptr(T()), _mem(_mem_t(mem)), _size(len) { /* NOP */ } //! Index operator gets the value of rv[index] - const T &operator[](size_t index) const{ + const T& operator[](size_t index) const + { return _mem[index]; } //! The number of elements in this container - size_t size(void) const{ + size_t size(void) const + { return _size; } private: - const T _ptr; - typedef T* _mem_t; + const T _ptr; + typedef T* _mem_t; const _mem_t _mem; const size_t _size; }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_REF_VECTOR_HPP */ diff --git a/host/include/uhd/types/sensors.hpp b/host/include/uhd/types/sensors.hpp index 4f1b64534..5423f2423 100644 --- a/host/include/uhd/types/sensors.hpp +++ b/host/include/uhd/types/sensors.hpp @@ -12,142 +12,127 @@ #include <map> #include <string> -namespace uhd{ +namespace uhd { + +/*! + * A sensor value stores a sensor reading as a string with unit and data type. + * The sensor value class can be used in the following way: + * + * sensor_value_t ref_lock_sensor("Reference", my_lock, "unlocked", "locked"); + * std::cout << ref_lock_sensor.to_pp_string() << std::endl; + * //prints Reference: locked + * + * sensor_value_t temp_sensor("Temperature", my_temp, "C"); + * std::cout << temp_sensor.to_pp_string() << std::endl; + * //prints Temperature: 38.5 C + */ +struct UHD_API sensor_value_t +{ + typedef std::map<std::string, std::string> sensor_map_t; /*! - * A sensor value stores a sensor reading as a string with unit and data type. - * The sensor value class can be used in the following way: + * Create a sensor value from a boolean. + * \param name the name of the sensor + * \param value the value true or false + * \param utrue the unit string when value is true + * \param ufalse the unit string when value is false + */ + sensor_value_t(const std::string& name, + bool value, + const std::string& utrue, + const std::string& ufalse); + + /*! + * Create a sensor value from an integer. + * \param name the name of the sensor + * \param value the signed integer value + * \param unit the associated unit type + * \param formatter the formatter string + */ + sensor_value_t(const std::string& name, + signed value, + const std::string& unit, + const std::string& formatter = "%d"); + + /*! + * Create a sensor value from a real number. + * \param name the name of the sensor + * \param value the real number value + * \param unit the associated unit type + * \param formatter the formatter string + */ + sensor_value_t(const std::string& name, + double value, + const std::string& unit, + const std::string& formatter = "%f"); + + /*! + * Create a sensor value from a string. + * \param name the name of the sensor + * \param value the real number value + * \param unit the associated unit type + */ + sensor_value_t( + const std::string& name, const std::string& value, const std::string& unit); + + /*! + * Create a sensor value from a map. * - * sensor_value_t ref_lock_sensor("Reference", my_lock, "unlocked", "locked"); - * std::cout << ref_lock_sensor.to_pp_string() << std::endl; - * //prints Reference: locked + * The map must have the following keys: name, type, value, and unit. * - * sensor_value_t temp_sensor("Temperature", my_temp, "C"); - * std::cout << temp_sensor.to_pp_string() << std::endl; - * //prints Temperature: 38.5 C + * type must one of the following strings: BOOLEAN, INTEGER, REALNUM, + * or STRING (see data_type_t). */ - struct UHD_API sensor_value_t{ - typedef std::map<std::string, std::string> sensor_map_t; - - /*! - * Create a sensor value from a boolean. - * \param name the name of the sensor - * \param value the value true or false - * \param utrue the unit string when value is true - * \param ufalse the unit string when value is false - */ - sensor_value_t( - const std::string &name, - bool value, - const std::string &utrue, - const std::string &ufalse - ); - - /*! - * Create a sensor value from an integer. - * \param name the name of the sensor - * \param value the signed integer value - * \param unit the associated unit type - * \param formatter the formatter string - */ - sensor_value_t( - const std::string &name, - signed value, - const std::string &unit, - const std::string &formatter = "%d" - ); - - /*! - * Create a sensor value from a real number. - * \param name the name of the sensor - * \param value the real number value - * \param unit the associated unit type - * \param formatter the formatter string - */ - sensor_value_t( - const std::string &name, - double value, - const std::string &unit, - const std::string &formatter = "%f" - ); - - /*! - * Create a sensor value from a string. - * \param name the name of the sensor - * \param value the real number value - * \param unit the associated unit type - */ - sensor_value_t( - const std::string &name, - const std::string &value, - const std::string &unit - ); - - /*! - * Create a sensor value from a map. - * - * The map must have the following keys: name, type, value, and unit. - * - * type must one of the following strings: BOOLEAN, INTEGER, REALNUM, - * or STRING (see data_type_t). - */ - sensor_value_t( - const std::map<std::string, std::string> &sensor_dict - ); - - /*! - * Create a sensor value from another sensor value. - * \param source the source sensor value to copy - */ - sensor_value_t(const sensor_value_t& source); - - //! convert the sensor value to a boolean - bool to_bool(void) const; - - //! convert the sensor value to an integer - signed to_int(void) const; - - //! convert the sensor value to real number - double to_real(void) const; - - //! convert the sensor value to sensor_map_t - sensor_map_t to_map(void) const; - - //! The name of the sensor value - std::string name; - - /*! - * The sensor value as a string. - * For integer and real number types, this will be the output of the formatter. - * For boolean types, the value will be the string literal "true" or "false". - */ - std::string value; - - /*! - * The sensor value's unit type. - * For boolean types, this will be the one of the two units - * depending upon the value of the boolean true or false. - */ - std::string unit; - - //! Enumeration of possible data types in a sensor - enum data_type_t { - BOOLEAN = 'b', - INTEGER = 'i', - REALNUM = 'r', - STRING = 's' - }; - - //! The data type of the value - data_type_t type; - - //! Convert this sensor value into a printable string - std::string to_pp_string(void) const; - - //! Assignment operator for sensor value - sensor_value_t& operator=(const sensor_value_t& value); - }; - -} //namespace uhd + sensor_value_t(const std::map<std::string, std::string>& sensor_dict); + + /*! + * Create a sensor value from another sensor value. + * \param source the source sensor value to copy + */ + sensor_value_t(const sensor_value_t& source); + + //! convert the sensor value to a boolean + bool to_bool(void) const; + + //! convert the sensor value to an integer + signed to_int(void) const; + + //! convert the sensor value to real number + double to_real(void) const; + + //! convert the sensor value to sensor_map_t + sensor_map_t to_map(void) const; + + //! The name of the sensor value + std::string name; + + /*! + * The sensor value as a string. + * For integer and real number types, this will be the output of the formatter. + * For boolean types, the value will be the string literal "true" or "false". + */ + std::string value; + + /*! + * The sensor value's unit type. + * For boolean types, this will be the one of the two units + * depending upon the value of the boolean true or false. + */ + std::string unit; + + //! Enumeration of possible data types in a sensor + enum data_type_t { BOOLEAN = 'b', INTEGER = 'i', REALNUM = 'r', STRING = 's' }; + + //! The data type of the value + data_type_t type; + + //! Convert this sensor value into a printable string + std::string to_pp_string(void) const; + + //! Assignment operator for sensor value + sensor_value_t& operator=(const sensor_value_t& value); +}; + +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_SENSORS_HPP */ diff --git a/host/include/uhd/types/serial.hpp b/host/include/uhd/types/serial.hpp index 5ede2d4f5..b68c68870 100644 --- a/host/include/uhd/types/serial.hpp +++ b/host/include/uhd/types/serial.hpp @@ -9,198 +9,176 @@ #define INCLUDED_UHD_TYPES_SERIAL_HPP #include <uhd/config.hpp> -#include <boost/shared_ptr.hpp> #include <stdint.h> +#include <boost/shared_ptr.hpp> #include <vector> -namespace uhd{ +namespace uhd { + +/*! + * Byte vector typedef for passing data in and out of I2C interfaces. + */ +typedef std::vector<uint8_t> byte_vector_t; + +/*! + * The i2c interface class: + * Provides i2c and eeprom functionality. + * A subclass should only have to implement the i2c routines. + * An eeprom implementation comes for free with the interface. + * + * The eeprom routines are implemented on top of i2c. + * The built in eeprom implementation only does single + * byte reads and byte writes over the i2c interface, + * so it should be portable across multiple eeproms. + * Override the eeprom routines if this is not acceptable. + */ +class UHD_API i2c_iface +{ +public: + typedef boost::shared_ptr<i2c_iface> sptr; + + virtual ~i2c_iface(void); + + //! Create an i2c_iface than can talk to 16 bit addressable EEPROMS + i2c_iface::sptr eeprom16(void); + + /*! + * Write bytes over the i2c. + * \param addr the address + * \param buf the vector of bytes + */ + virtual void write_i2c(uint16_t addr, const byte_vector_t& buf) = 0; + + /*! + * Read bytes over the i2c. + * \param addr the address + * \param num_bytes number of bytes to read + * \return a vector of bytes + */ + virtual byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) = 0; + + /*! + * Write bytes to an eeprom. + * \param addr the address + * \param offset byte offset + * \param buf the vector of bytes + */ + virtual void write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& buf); + + /*! + * Read bytes from an eeprom. + * \param addr the address + * \param offset byte offset + * \param num_bytes number of bytes to read + * \return a vector of bytes + */ + virtual byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes); +}; + +/*! + * The SPI configuration struct: + * Used to configure a SPI transaction interface. + */ +struct UHD_API spi_config_t +{ + /*! + * The edge type specifies when data is valid + * relative to the edge of the serial clock. + */ + enum edge_t { EDGE_RISE = 'r', EDGE_FALL = 'f' }; + + //! on what edge is the mosi data valid? + edge_t mosi_edge; + + //! on what edge is the miso data valid? + edge_t miso_edge; + + //! Set the clock speed for this transaction + bool use_custom_divider; + + //! Optionally set the SPI clock divider for this transaction + size_t divider; + + /*! + * Create a new spi config. + * \param edge the default edge for mosi and miso + */ + spi_config_t(edge_t edge = EDGE_RISE); +}; + +/*! + * The SPI interface class. + * Provides routines to transact SPI and do other useful things which haven't been defined + * yet. + */ +class UHD_API spi_iface +{ +public: + typedef boost::shared_ptr<spi_iface> sptr; + + virtual ~spi_iface(void); /*! - * Byte vector typedef for passing data in and out of I2C interfaces. + * Perform a spi transaction. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data + * \param readback true to readback a value + * \return spi data if readback set */ - typedef std::vector<uint8_t> byte_vector_t; + virtual uint32_t transact_spi(int which_slave, + const spi_config_t& config, + uint32_t data, + size_t num_bits, + bool readback) = 0; /*! - * The i2c interface class: - * Provides i2c and eeprom functionality. - * A subclass should only have to implement the i2c routines. - * An eeprom implementation comes for free with the interface. - * - * The eeprom routines are implemented on top of i2c. - * The built in eeprom implementation only does single - * byte reads and byte writes over the i2c interface, - * so it should be portable across multiple eeproms. - * Override the eeprom routines if this is not acceptable. + * Read from the SPI bus. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write out (be sure to set write bit) + * \param num_bits how many bits in data + * \return spi data */ - class UHD_API i2c_iface{ - public: - typedef boost::shared_ptr<i2c_iface> sptr; - - virtual ~i2c_iface(void); - - //! Create an i2c_iface than can talk to 16 bit addressable EEPROMS - i2c_iface::sptr eeprom16(void); - - /*! - * Write bytes over the i2c. - * \param addr the address - * \param buf the vector of bytes - */ - virtual void write_i2c( - uint16_t addr, - const byte_vector_t &buf - ) = 0; - - /*! - * Read bytes over the i2c. - * \param addr the address - * \param num_bytes number of bytes to read - * \return a vector of bytes - */ - virtual byte_vector_t read_i2c( - uint16_t addr, - size_t num_bytes - ) = 0; - - /*! - * Write bytes to an eeprom. - * \param addr the address - * \param offset byte offset - * \param buf the vector of bytes - */ - virtual void write_eeprom( - uint16_t addr, - uint16_t offset, - const byte_vector_t &buf - ); - - /*! - * Read bytes from an eeprom. - * \param addr the address - * \param offset byte offset - * \param num_bytes number of bytes to read - * \return a vector of bytes - */ - virtual byte_vector_t read_eeprom( - uint16_t addr, - uint16_t offset, - size_t num_bytes - ); - }; + virtual uint32_t read_spi( + int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits); /*! - * The SPI configuration struct: - * Used to configure a SPI transaction interface. + * Write to the SPI bus. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data */ - struct UHD_API spi_config_t{ - /*! - * The edge type specifies when data is valid - * relative to the edge of the serial clock. - */ - enum edge_t{ - EDGE_RISE = 'r', - EDGE_FALL = 'f' - }; - - //! on what edge is the mosi data valid? - edge_t mosi_edge; - - //! on what edge is the miso data valid? - edge_t miso_edge; - - //! Set the clock speed for this transaction - bool use_custom_divider; - - //! Optionally set the SPI clock divider for this transaction - size_t divider; - - /*! - * Create a new spi config. - * \param edge the default edge for mosi and miso - */ - spi_config_t(edge_t edge = EDGE_RISE); - }; + virtual void write_spi( + int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits); +}; + +/*! + * UART interface to write and read strings. + */ +class UHD_API uart_iface +{ +public: + typedef boost::shared_ptr<uart_iface> sptr; + + virtual ~uart_iface(void); /*! - * The SPI interface class. - * Provides routines to transact SPI and do other useful things which haven't been defined yet. + * Write to a serial port. + * \param buf the data to write */ - class UHD_API spi_iface{ - public: - typedef boost::shared_ptr<spi_iface> sptr; - - virtual ~spi_iface(void); - - /*! - * Perform a spi transaction. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write - * \param num_bits how many bits in data - * \param readback true to readback a value - * \return spi data if readback set - */ - virtual uint32_t transact_spi( - int which_slave, - const spi_config_t &config, - uint32_t data, - size_t num_bits, - bool readback - ) = 0; - - /*! - * Read from the SPI bus. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write out (be sure to set write bit) - * \param num_bits how many bits in data - * \return spi data - */ - virtual uint32_t read_spi( - int which_slave, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); - - /*! - * Write to the SPI bus. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write - * \param num_bits how many bits in data - */ - virtual void write_spi( - int which_slave, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ); - }; + virtual void write_uart(const std::string& buf) = 0; /*! - * UART interface to write and read strings. + * Read a line from a serial port. + * \param timeout the timeout in seconds + * \return the line or empty string upon timeout */ - class UHD_API uart_iface{ - public: - typedef boost::shared_ptr<uart_iface> sptr; - - virtual ~uart_iface(void); - - /*! - * Write to a serial port. - * \param buf the data to write - */ - virtual void write_uart(const std::string &buf) = 0; - - /*! - * Read a line from a serial port. - * \param timeout the timeout in seconds - * \return the line or empty string upon timeout - */ - virtual std::string read_uart(double timeout) = 0; - }; - -} //namespace uhd + virtual std::string read_uart(double timeout) = 0; +}; + +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_SERIAL_HPP */ diff --git a/host/include/uhd/types/sid.hpp b/host/include/uhd/types/sid.hpp index bb92646d0..fe3ac1ac7 100644 --- a/host/include/uhd/types/sid.hpp +++ b/host/include/uhd/types/sid.hpp @@ -9,229 +9,261 @@ #define INCLUDED_UHD_TYPES_SID_HPP #include <uhd/config.hpp> -#include <iostream> #include <stdint.h> +#include <iostream> namespace uhd { - /*! - * \brief Represents a stream ID (SID). - * - * A stream ID (SID) is an identifier for data. - * It is a 32-Bit value which consists of 16 Bits - * for the source address and 16 Bits for the destination - * address. - * Every address is split into two parts: The _address_, which - * identifies the device used, and the _endpoint_, which identifies - * a specific object inside the given device (e.g., a block). - * *Note:* In the case where there are several crossbars on a single - * device, each crossbar gets its own address. - * Both address and endpoint are 8 bits in length. If a 16-bit address - * is required, we use the combination of the 8-bit address and the 8-bit - * endpoint. - * - * <pre> - * +-------------+--------------+-------------+--------------+ - * | SRC address | SRC endpoint | DST address | DST endpoint | - * +-------------+--------------+-------------+--------------+ - * </pre> - * - * \section sid_str_repr String Representation (pretty printing) - * - * The string representation of a SID is of the form - * - * 2.3>0.6 - * - * The '>' symbol shows the direction, so in this case, - * data is flowing from address 2.3 to 0.6. - * - * As a convention, ':' is used instead of '.' when giving the - * SID in hexadecimal numbers, and two characters are used for each - * address part. As an example, the following two SIDs are identical: - * - * 2.3>0.16 (decimal) - * 02:03>00:10 (hexadecimal) - * - * The format is: - * SRC_ADDRESS.SRC_ENDPOINT>DST_ADDRESS.DST_ENDPOINT - * - * - * \section sid_block_ports Block Ports - * - * In the special case where a block on a crossbar is addressed, the - * endpoint is further split up into two parts of four bits each: The - * first four bits specify the port number on the crossbar, whereas the - * lower four bits represent the *block port*. As an example, consider - * the following SID, given in hexadecimal: - * - * 00:10>02:A1 - * - * In this example, assume data is flowing from the host computer to an - * X300. The crossbar address is 02. The endpoint is A1, which means we - * are accessing a block on crossbar port A (the tenth port), and are addressing - * block port 1. - * - */ - class UHD_API sid_t - { - public: - //! Create an unset SID - sid_t(); - //! Create a sid_t object from a 32-Bit SID value - sid_t(uint32_t sid); - //! Create a sid_t object from its four components - sid_t(uint8_t src_addr, uint8_t src_ep, uint8_t dst_addr, uint8_t dst_ep); - //! Convert a string representation of a SID into its numerical representation - sid_t(const std::string &); - - //! Return a decimal string representation of the SID. - std::string to_pp_string() const; - //! Return a hexadecimal string representation of the SID. - std::string to_pp_string_hex() const; - - //! Returns true if this actually holds a valid SID - bool is_set() const { return _set; }; - - // Getters - // - //! Alias for get_sid() - inline uint32_t get() const { return get_sid(); }; - //! Returns a 32-Bit representation of the SID if set, or zero otherwise. - inline uint32_t get_sid() const { return _set ? _sid : 0; }; - //! Return the 16-bit source address of this SID - inline uint32_t get_src() const { - return (_sid >> 16) & 0xFFFF; - } - //! Return the 16-bit destination address of this SID - inline uint32_t get_dst() const { - return _sid & 0xFFFF; - } - //! Return 8-bit address of the source - inline uint32_t get_src_addr() const { - return (get_src() >> 8) & 0xFF; - } - //! Return endpoint of the source - inline uint32_t get_src_endpoint() const { - return get_src() & 0xFF; - } - //! Return crossbar port of the source - inline uint32_t get_src_xbarport() const { - return (get_src_endpoint() >> 4) & 0xF; - } - //! Return block port of the source - inline uint32_t get_src_blockport() const { - return (get_src_endpoint()) & 0xF; - } - //! Return 8-bit address of the destination - inline uint32_t get_dst_addr() const { - return (get_dst() >> 8) & 0xFF; - } - //! Return endpoint of the destination - inline uint32_t get_dst_endpoint() const { - return get_dst() & 0xFF; - } - //! Return crossbar port of the source - inline uint32_t get_dst_xbarport() const { - return (get_dst_endpoint() >> 4) & 0xF; - } - //! Return block port of the source - inline uint32_t get_dst_blockport() const { - return (get_dst_endpoint()) & 0xF; - } - - // Setters - - //! Alias for set_sid() - void set(uint32_t new_sid) { set_sid(new_sid); }; - //! Convert a string representation of a SID into a numerical one - // Throws uhd::value_error if the string is not a valid SID - // representation. - void set_from_str(const std::string &); - void set_sid(uint32_t new_sid); - //! Set the source address of this SID - // (the first 16 Bits) - void set_src(uint32_t new_addr); - //! Set the destination address of this SID - // (the last 16 Bits) - void set_dst(uint32_t new_addr); - void set_src_addr(uint32_t new_addr); - void set_src_endpoint(uint32_t new_addr); - void set_dst_addr(uint32_t new_addr); - void set_dst_endpoint(uint32_t new_addr); - void set_dst_xbarport(uint32_t new_xbarport); - void set_dst_blockport(uint32_t new_blockport); - - // Manipulators - - //! Swaps dst and src address and returns the new SID. - sid_t reversed() const; - - //! Swaps dst and src in-place. This modifies the current SID. - void reverse(); - - // Overloaded operators - - sid_t operator = (const uint32_t new_sid) { - set_sid(new_sid); - return *this; - } - - sid_t operator = (sid_t &sid) { - set_sid(sid.get_sid()); - return *this; - } - - sid_t operator = (const sid_t &sid) { - set_sid(sid.get_sid()); - return *this; - } - - sid_t operator = (const std::string &sid_str) { - set_from_str(sid_str); - return *this; - } - - bool operator == (const sid_t &sid) const { - return (not _set and not sid.is_set()) or (_sid == sid.get_sid()); - } - - bool operator == (uint32_t sid) const { - return _set and _sid == sid; - } - - bool operator == (const std::string &sid_str) const { - sid_t rhs(sid_str); - return *this == rhs; - } - - // overloaded type casts are tricky, but for now we'll need them - // for backward compatibility. consider them deprecated. - - //! If the SID is not set, always returns zero. - // Use is_set() to check if the return value is valid. - operator uint32_t() const { - return get(); - } - - operator bool() const { - return _set; - } - - private: - uint32_t _sid; - bool _set; +/*! + * \brief Represents a stream ID (SID). + * + * A stream ID (SID) is an identifier for data. + * It is a 32-Bit value which consists of 16 Bits + * for the source address and 16 Bits for the destination + * address. + * Every address is split into two parts: The _address_, which + * identifies the device used, and the _endpoint_, which identifies + * a specific object inside the given device (e.g., a block). + * *Note:* In the case where there are several crossbars on a single + * device, each crossbar gets its own address. + * Both address and endpoint are 8 bits in length. If a 16-bit address + * is required, we use the combination of the 8-bit address and the 8-bit + * endpoint. + * + * <pre> + * +-------------+--------------+-------------+--------------+ + * | SRC address | SRC endpoint | DST address | DST endpoint | + * +-------------+--------------+-------------+--------------+ + * </pre> + * + * \section sid_str_repr String Representation (pretty printing) + * + * The string representation of a SID is of the form + * + * 2.3>0.6 + * + * The '>' symbol shows the direction, so in this case, + * data is flowing from address 2.3 to 0.6. + * + * As a convention, ':' is used instead of '.' when giving the + * SID in hexadecimal numbers, and two characters are used for each + * address part. As an example, the following two SIDs are identical: + * + * 2.3>0.16 (decimal) + * 02:03>00:10 (hexadecimal) + * + * The format is: + * SRC_ADDRESS.SRC_ENDPOINT>DST_ADDRESS.DST_ENDPOINT + * + * + * \section sid_block_ports Block Ports + * + * In the special case where a block on a crossbar is addressed, the + * endpoint is further split up into two parts of four bits each: The + * first four bits specify the port number on the crossbar, whereas the + * lower four bits represent the *block port*. As an example, consider + * the following SID, given in hexadecimal: + * + * 00:10>02:A1 + * + * In this example, assume data is flowing from the host computer to an + * X300. The crossbar address is 02. The endpoint is A1, which means we + * are accessing a block on crossbar port A (the tenth port), and are addressing + * block port 1. + * + */ +class UHD_API sid_t +{ +public: + //! Create an unset SID + sid_t(); + //! Create a sid_t object from a 32-Bit SID value + sid_t(uint32_t sid); + //! Create a sid_t object from its four components + sid_t(uint8_t src_addr, uint8_t src_ep, uint8_t dst_addr, uint8_t dst_ep); + //! Convert a string representation of a SID into its numerical representation + sid_t(const std::string&); + + //! Return a decimal string representation of the SID. + std::string to_pp_string() const; + //! Return a hexadecimal string representation of the SID. + std::string to_pp_string_hex() const; + + //! Returns true if this actually holds a valid SID + bool is_set() const + { + return _set; + }; + + // Getters + // + //! Alias for get_sid() + inline uint32_t get() const + { + return get_sid(); + }; + //! Returns a 32-Bit representation of the SID if set, or zero otherwise. + inline uint32_t get_sid() const + { + return _set ? _sid : 0; + }; + //! Return the 16-bit source address of this SID + inline uint32_t get_src() const + { + return (_sid >> 16) & 0xFFFF; + } + //! Return the 16-bit destination address of this SID + inline uint32_t get_dst() const + { + return _sid & 0xFFFF; + } + //! Return 8-bit address of the source + inline uint32_t get_src_addr() const + { + return (get_src() >> 8) & 0xFF; + } + //! Return endpoint of the source + inline uint32_t get_src_endpoint() const + { + return get_src() & 0xFF; + } + //! Return crossbar port of the source + inline uint32_t get_src_xbarport() const + { + return (get_src_endpoint() >> 4) & 0xF; + } + //! Return block port of the source + inline uint32_t get_src_blockport() const + { + return (get_src_endpoint()) & 0xF; + } + //! Return 8-bit address of the destination + inline uint32_t get_dst_addr() const + { + return (get_dst() >> 8) & 0xFF; + } + //! Return endpoint of the destination + inline uint32_t get_dst_endpoint() const + { + return get_dst() & 0xFF; + } + //! Return crossbar port of the source + inline uint32_t get_dst_xbarport() const + { + return (get_dst_endpoint() >> 4) & 0xF; + } + //! Return block port of the source + inline uint32_t get_dst_blockport() const + { + return (get_dst_endpoint()) & 0xF; + } + + // Setters + + //! Alias for set_sid() + void set(uint32_t new_sid) + { + set_sid(new_sid); }; + //! Convert a string representation of a SID into a numerical one + // Throws uhd::value_error if the string is not a valid SID + // representation. + void set_from_str(const std::string&); + void set_sid(uint32_t new_sid); + //! Set the source address of this SID + // (the first 16 Bits) + void set_src(uint32_t new_addr); + //! Set the destination address of this SID + // (the last 16 Bits) + void set_dst(uint32_t new_addr); + void set_src_addr(uint32_t new_addr); + void set_src_endpoint(uint32_t new_addr); + void set_dst_addr(uint32_t new_addr); + void set_dst_endpoint(uint32_t new_addr); + void set_dst_xbarport(uint32_t new_xbarport); + void set_dst_blockport(uint32_t new_blockport); + + // Manipulators + + //! Swaps dst and src address and returns the new SID. + sid_t reversed() const; + + //! Swaps dst and src in-place. This modifies the current SID. + void reverse(); + + // Overloaded operators + + sid_t operator=(const uint32_t new_sid) + { + set_sid(new_sid); + return *this; + } + + sid_t operator=(sid_t& sid) + { + set_sid(sid.get_sid()); + return *this; + } + + sid_t operator=(const sid_t& sid) + { + set_sid(sid.get_sid()); + return *this; + } + + sid_t operator=(const std::string& sid_str) + { + set_from_str(sid_str); + return *this; + } + + bool operator==(const sid_t& sid) const + { + return (not _set and not sid.is_set()) or (_sid == sid.get_sid()); + } + + bool operator==(uint32_t sid) const + { + return _set and _sid == sid; + } + + bool operator==(const std::string& sid_str) const + { + sid_t rhs(sid_str); + return *this == rhs; + } + + // overloaded type casts are tricky, but for now we'll need them + // for backward compatibility. consider them deprecated. + + //! If the SID is not set, always returns zero. + // Use is_set() to check if the return value is valid. + operator uint32_t() const + { + return get(); + } + + operator bool() const + { + return _set; + } + +private: + uint32_t _sid; + bool _set; +}; - //! Stream output operator. Honors std::ios::hex. - inline std::ostream& operator<< (std::ostream& out, const sid_t &sid) { - std::ios_base::fmtflags ff = out.flags(); - if (ff & std::ios::hex) { - out << sid.to_pp_string_hex(); - } else { - out << sid.to_pp_string(); - } - return out; +//! Stream output operator. Honors std::ios::hex. +inline std::ostream& operator<<(std::ostream& out, const sid_t& sid) +{ + std::ios_base::fmtflags ff = out.flags(); + if (ff & std::ios::hex) { + out << sid.to_pp_string_hex(); + } else { + out << sid.to_pp_string(); } + return out; +} -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_SID_HPP */ diff --git a/host/include/uhd/types/stream_cmd.hpp b/host/include/uhd/types/stream_cmd.hpp index 5628e8d92..9cd1e581f 100644 --- a/host/include/uhd/types/stream_cmd.hpp +++ b/host/include/uhd/types/stream_cmd.hpp @@ -11,43 +11,43 @@ #include <uhd/config.hpp> #include <uhd/types/time_spec.hpp> -namespace uhd{ - - /*! - * Command struct for configuration and control of streaming: - * - * A stream command defines how the device sends samples to the host. - * Streaming is controlled by submitting a stream command to the rx dsp. - * Granular control over what the device streams to the host can be - * achieved through submission of multiple (carefully-crafted) commands. - * - * The mode parameter controls how streaming is issued to the device: - * - "Start continuous" tells the device to stream samples indefinitely. - * - "Stop continuous" tells the device to end continuous streaming. - * - "Num samps and done" tells the device to stream num samps and - * to not expect a future stream command for contiguous samples. - * - "Num samps and more" tells the device to stream num samps and - * to expect a future stream command for contiguous samples. - * - * The stream now parameter controls when the stream begins. - * When true, the device will begin streaming ASAP. When false, - * the device will begin streaming at a time specified by time_spec. - */ - struct UHD_API stream_cmd_t{ - - enum stream_mode_t { - STREAM_MODE_START_CONTINUOUS = int('a'), - STREAM_MODE_STOP_CONTINUOUS = int('o'), - STREAM_MODE_NUM_SAMPS_AND_DONE = int('d'), - STREAM_MODE_NUM_SAMPS_AND_MORE = int('m') - } stream_mode; - size_t num_samps; - - bool stream_now; - time_spec_t time_spec; - - stream_cmd_t(const stream_mode_t &stream_mode); - }; +namespace uhd { + +/*! + * Command struct for configuration and control of streaming: + * + * A stream command defines how the device sends samples to the host. + * Streaming is controlled by submitting a stream command to the rx dsp. + * Granular control over what the device streams to the host can be + * achieved through submission of multiple (carefully-crafted) commands. + * + * The mode parameter controls how streaming is issued to the device: + * - "Start continuous" tells the device to stream samples indefinitely. + * - "Stop continuous" tells the device to end continuous streaming. + * - "Num samps and done" tells the device to stream num samps and + * to not expect a future stream command for contiguous samples. + * - "Num samps and more" tells the device to stream num samps and + * to expect a future stream command for contiguous samples. + * + * The stream now parameter controls when the stream begins. + * When true, the device will begin streaming ASAP. When false, + * the device will begin streaming at a time specified by time_spec. + */ +struct UHD_API stream_cmd_t +{ + enum stream_mode_t { + STREAM_MODE_START_CONTINUOUS = int('a'), + STREAM_MODE_STOP_CONTINUOUS = int('o'), + STREAM_MODE_NUM_SAMPS_AND_DONE = int('d'), + STREAM_MODE_NUM_SAMPS_AND_MORE = int('m') + } stream_mode; + size_t num_samps; + + bool stream_now; + time_spec_t time_spec; + + stream_cmd_t(const stream_mode_t& stream_mode); +}; } /* namespace uhd */ diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp index c8d5443a0..89655807e 100644 --- a/host/include/uhd/types/time_spec.hpp +++ b/host/include/uhd/types/time_spec.hpp @@ -9,122 +9,123 @@ #define INCLUDED_UHD_TYPES_TIME_SPEC_HPP #include <uhd/config.hpp> -#include <boost/operators.hpp> #include <stdint.h> +#include <boost/operators.hpp> -namespace uhd{ +namespace uhd { + +/*! + * A time_spec_t holds a seconds and a fractional seconds time value. + * Depending upon usage, the time_spec_t can represent absolute times, + * relative times, or time differences (between absolute times). + * + * The time_spec_t provides clock-domain independent time storage, + * but can convert fractional seconds to/from clock-domain specific units. + * + * The fractional seconds are stored as double precision floating point. + * This gives the fractional seconds enough precision to unambiguously + * specify a clock-tick/sample-count up to rates of several petahertz. + */ +class UHD_API time_spec_t : boost::additive<time_spec_t>, + boost::additive<time_spec_t, double>, + boost::totally_ordered<time_spec_t> +{ +public: + /*! + * Create a time_spec_t from a real-valued seconds count. + * \param secs the real-valued seconds count (default = 0) + */ + time_spec_t(double secs = 0); + + /*! + * Create a time_spec_t from whole and fractional seconds. + * \param full_secs the whole/integer seconds count + * \param frac_secs the fractional seconds count (default = 0) + */ + time_spec_t(int64_t full_secs, double frac_secs = 0); + + /*! + * Create a time_spec_t from whole seconds and fractional ticks. + * Translation from clock-domain specific units. + * \param full_secs the whole/integer seconds count + * \param tick_count the fractional seconds tick count + * \param tick_rate the number of ticks per second + */ + time_spec_t(int64_t full_secs, long tick_count, double tick_rate); + + /*! + * Create a time_spec_t from a 64-bit tick count. + * Translation from clock-domain specific units. + * \param ticks an integer count of ticks + * \param tick_rate the number of ticks per second + */ + static time_spec_t from_ticks(long long ticks, double tick_rate); + + /*! + * Convert the fractional seconds to clock ticks. + * Translation into clock-domain specific units. + * \param tick_rate the number of ticks per second + * \return the fractional seconds tick count + */ + long get_tick_count(double tick_rate) const; + + /*! + * Convert the time spec into a 64-bit tick count. + * Translation into clock-domain specific units. + * \param tick_rate the number of ticks per second + * \return an integer number of ticks + */ + long long to_ticks(const double tick_rate) const; + + /*! + * Get the time as a real-valued seconds count. + * Note: If this time_spec_t represents an absolute time, + * the precision of the fractional seconds may be lost. + * \return the real-valued seconds + */ + double get_real_secs(void) const; + + /*! + * Get the whole/integer part of the time in seconds. + * \return the whole/integer seconds + */ + int64_t get_full_secs(void) const; /*! - * A time_spec_t holds a seconds and a fractional seconds time value. - * Depending upon usage, the time_spec_t can represent absolute times, - * relative times, or time differences (between absolute times). - * - * The time_spec_t provides clock-domain independent time storage, - * but can convert fractional seconds to/from clock-domain specific units. - * - * The fractional seconds are stored as double precision floating point. - * This gives the fractional seconds enough precision to unambiguously - * specify a clock-tick/sample-count up to rates of several petahertz. + * Get the fractional part of the time in seconds. + * \return the fractional seconds */ - class UHD_API time_spec_t : - boost::additive<time_spec_t>, - boost::additive<time_spec_t, double>, - boost::totally_ordered<time_spec_t>{ - public: - - /*! - * Create a time_spec_t from a real-valued seconds count. - * \param secs the real-valued seconds count (default = 0) - */ - time_spec_t(double secs = 0); - - /*! - * Create a time_spec_t from whole and fractional seconds. - * \param full_secs the whole/integer seconds count - * \param frac_secs the fractional seconds count (default = 0) - */ - time_spec_t(int64_t full_secs, double frac_secs = 0); - - /*! - * Create a time_spec_t from whole seconds and fractional ticks. - * Translation from clock-domain specific units. - * \param full_secs the whole/integer seconds count - * \param tick_count the fractional seconds tick count - * \param tick_rate the number of ticks per second - */ - time_spec_t(int64_t full_secs, long tick_count, double tick_rate); - - /*! - * Create a time_spec_t from a 64-bit tick count. - * Translation from clock-domain specific units. - * \param ticks an integer count of ticks - * \param tick_rate the number of ticks per second - */ - static time_spec_t from_ticks(long long ticks, double tick_rate); - - /*! - * Convert the fractional seconds to clock ticks. - * Translation into clock-domain specific units. - * \param tick_rate the number of ticks per second - * \return the fractional seconds tick count - */ - long get_tick_count(double tick_rate) const; - - /*! - * Convert the time spec into a 64-bit tick count. - * Translation into clock-domain specific units. - * \param tick_rate the number of ticks per second - * \return an integer number of ticks - */ - long long to_ticks(const double tick_rate) const; - - /*! - * Get the time as a real-valued seconds count. - * Note: If this time_spec_t represents an absolute time, - * the precision of the fractional seconds may be lost. - * \return the real-valued seconds - */ - double get_real_secs(void) const; - - /*! - * Get the whole/integer part of the time in seconds. - * \return the whole/integer seconds - */ - int64_t get_full_secs(void) const; - - /*! - * Get the fractional part of the time in seconds. - * \return the fractional seconds - */ - double get_frac_secs(void) const; - - //! Implement addable interface - time_spec_t &operator+=(const time_spec_t &); - time_spec_t &operator+=(double &); - //! Implement subtractable interface - time_spec_t &operator-=(const time_spec_t &); - time_spec_t &operator-=(double &); - - //private time storage details - private: - int64_t _full_secs; - double _frac_secs; - }; - - //! Implement equality_comparable interface - UHD_API bool operator==(const time_spec_t &, const time_spec_t &); - - //! Implement less_than_comparable interface - UHD_API bool operator<(const time_spec_t &, const time_spec_t &); - - UHD_INLINE int64_t time_spec_t::get_full_secs(void) const{ - return this->_full_secs; - } - - UHD_INLINE double time_spec_t::get_frac_secs(void) const{ - return this->_frac_secs; - } - -} //namespace uhd + double get_frac_secs(void) const; + + //! Implement addable interface + time_spec_t& operator+=(const time_spec_t&); + time_spec_t& operator+=(double&); + //! Implement subtractable interface + time_spec_t& operator-=(const time_spec_t&); + time_spec_t& operator-=(double&); + + // private time storage details +private: + int64_t _full_secs; + double _frac_secs; +}; + +//! Implement equality_comparable interface +UHD_API bool operator==(const time_spec_t&, const time_spec_t&); + +//! Implement less_than_comparable interface +UHD_API bool operator<(const time_spec_t&, const time_spec_t&); + +UHD_INLINE int64_t time_spec_t::get_full_secs(void) const +{ + return this->_full_secs; +} + +UHD_INLINE double time_spec_t::get_frac_secs(void) const +{ + return this->_frac_secs; +} + +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_TIME_SPEC_HPP */ diff --git a/host/include/uhd/types/tune_request.hpp b/host/include/uhd/types/tune_request.hpp index ec7e70619..c85ca95a1 100644 --- a/host/include/uhd/types/tune_request.hpp +++ b/host/include/uhd/types/tune_request.hpp @@ -11,99 +11,99 @@ #include <uhd/config.hpp> #include <uhd/types/device_addr.hpp> -namespace uhd{ +namespace uhd { +/*! + * A tune request instructs the implementation how to tune the RF chain. + * The policies can be used to select automatic tuning or + * fined control over the daughterboard IF and DSP tuning. + * Not all combinations of policies are applicable. + * Convenience constructors are supplied for most use cases. + * + * See also \ref general_tuning + */ +struct UHD_API tune_request_t +{ /*! - * A tune request instructs the implementation how to tune the RF chain. - * The policies can be used to select automatic tuning or - * fined control over the daughterboard IF and DSP tuning. - * Not all combinations of policies are applicable. - * Convenience constructors are supplied for most use cases. - * - * See also \ref general_tuning + * Make a new tune request for a particular center frequency. + * Use an automatic policy for the RF and DSP frequency + * to tune the chain as close as possible to the target frequency. + * \param target_freq the target frequency in Hz */ - struct UHD_API tune_request_t{ - /*! - * Make a new tune request for a particular center frequency. - * Use an automatic policy for the RF and DSP frequency - * to tune the chain as close as possible to the target frequency. - * \param target_freq the target frequency in Hz - */ - tune_request_t(double target_freq = 0); - - /*! - * Make a new tune request for a particular center frequency. - * Use a manual policy for the RF frequency, - * and an automatic policy for the DSP frequency, - * to tune the chain as close as possible to the target frequency. - * \param target_freq the target frequency in Hz - * \param lo_off the LO offset frequency in Hz - */ - tune_request_t(double target_freq, double lo_off); + tune_request_t(double target_freq = 0); - //! Policy options for tunable elements in the RF chain. - enum policy_t { - //! Do not set this argument, use current setting. - POLICY_NONE = int('N'), - //! Automatically determine the argument's value. - POLICY_AUTO = int('A'), - //! Use the argument's value for the setting. - POLICY_MANUAL = int('M') - }; + /*! + * Make a new tune request for a particular center frequency. + * Use a manual policy for the RF frequency, + * and an automatic policy for the DSP frequency, + * to tune the chain as close as possible to the target frequency. + * \param target_freq the target frequency in Hz + * \param lo_off the LO offset frequency in Hz + */ + tune_request_t(double target_freq, double lo_off); - /*! - * The target frequency of the overall chain in Hz. - * Set this even if all policies are set to manual. - */ - double target_freq; + //! Policy options for tunable elements in the RF chain. + enum policy_t { + //! Do not set this argument, use current setting. + POLICY_NONE = int('N'), + //! Automatically determine the argument's value. + POLICY_AUTO = int('A'), + //! Use the argument's value for the setting. + POLICY_MANUAL = int('M') + }; - /*! - * The policy for the RF frequency. - * Automatic behavior: the target frequency + default LO offset. - */ - policy_t rf_freq_policy; + /*! + * The target frequency of the overall chain in Hz. + * Set this even if all policies are set to manual. + */ + double target_freq; - /*! - * The RF frequency in Hz. - * Set when the policy is set to manual. - */ - double rf_freq; + /*! + * The policy for the RF frequency. + * Automatic behavior: the target frequency + default LO offset. + */ + policy_t rf_freq_policy; - /*! - * The policy for the DSP frequency. - * Automatic behavior: the difference between the target and IF. - */ - policy_t dsp_freq_policy; + /*! + * The RF frequency in Hz. + * Set when the policy is set to manual. + */ + double rf_freq; - /*! - * The DSP frequency in Hz. - * Set when the policy is set to manual. - * - * Note that the meaning of the DSP frequency's sign differs between - * TX and RX operations. The target frequency is the result of - * `target_freq = rf_freq + sign * dsp_freq`. For TX, `sign` is - * negative, and for RX, `sign` is positive. - * Example: If both RF and DSP tuning policies are set to manual, and - * `rf_freq` is set to 1 GHz, and `dsp_freq` is set to 10 MHz, the - * actual target frequency is 990 MHz for a TX tune request, and - * 1010 MHz for an RX tune request. - */ - double dsp_freq; + /*! + * The policy for the DSP frequency. + * Automatic behavior: the difference between the target and IF. + */ + policy_t dsp_freq_policy; - /*! - * The args parameter is used to pass arbitrary key/value pairs. - * Possible keys used by args (depends on implementation): - * - * - mode_n: Allows the user to tell the daughterboard tune code - * to choose between an integer N divider or fractional N divider. - * Default is fractional N on boards that support fractional N tuning. - * Fractional N provides greater tuning accuracy at the expense of spurs. - * Possible options for this key: "integer" or "fractional". - */ - device_addr_t args; + /*! + * The DSP frequency in Hz. + * Set when the policy is set to manual. + * + * Note that the meaning of the DSP frequency's sign differs between + * TX and RX operations. The target frequency is the result of + * `target_freq = rf_freq + sign * dsp_freq`. For TX, `sign` is + * negative, and for RX, `sign` is positive. + * Example: If both RF and DSP tuning policies are set to manual, and + * `rf_freq` is set to 1 GHz, and `dsp_freq` is set to 10 MHz, the + * actual target frequency is 990 MHz for a TX tune request, and + * 1010 MHz for an RX tune request. + */ + double dsp_freq; - }; + /*! + * The args parameter is used to pass arbitrary key/value pairs. + * Possible keys used by args (depends on implementation): + * + * - mode_n: Allows the user to tell the daughterboard tune code + * to choose between an integer N divider or fractional N divider. + * Default is fractional N on boards that support fractional N tuning. + * Fractional N provides greater tuning accuracy at the expense of spurs. + * Possible options for this key: "integer" or "fractional". + */ + device_addr_t args; +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP */ diff --git a/host/include/uhd/types/tune_result.hpp b/host/include/uhd/types/tune_result.hpp index 50b4e9536..2860b50c6 100644 --- a/host/include/uhd/types/tune_result.hpp +++ b/host/include/uhd/types/tune_result.hpp @@ -11,68 +11,69 @@ #include <uhd/config.hpp> #include <string> -namespace uhd{ +namespace uhd { - /*! - * The tune result struct holds the RF and DSP tuned frequencies. - */ - struct UHD_API tune_result_t{ - /*! The target RF frequency, clipped to be within system range - * - * If the requested frequency is within the range of the system, then - * this variable will equal the requested frequency. If the requested - * frequency is outside of the tunable range, however, this variable - * will hold the value that it was 'clipped' to in order to keep tuning - * in-bounds. */ - double clipped_rf_freq; +/*! + * The tune result struct holds the RF and DSP tuned frequencies. + */ +struct UHD_API tune_result_t +{ + /*! The target RF frequency, clipped to be within system range + * + * If the requested frequency is within the range of the system, then + * this variable will equal the requested frequency. If the requested + * frequency is outside of the tunable range, however, this variable + * will hold the value that it was 'clipped' to in order to keep tuning + * in-bounds. */ + double clipped_rf_freq; - /*! Target RF Freq, including RF FE offset - * - * AUTO Tuning Policy: - * This variable holds the requested center frequency, plus any LO - * offset required by the radio front-end. Note that this is *not* the - * LO offset requested by the user (if one exists), but rather one - * required by the hardware (if required). - * - * MANUAL Tuning Policy: - * This variable equals the RF frequency in the tune request. */ - double target_rf_freq; + /*! Target RF Freq, including RF FE offset + * + * AUTO Tuning Policy: + * This variable holds the requested center frequency, plus any LO + * offset required by the radio front-end. Note that this is *not* the + * LO offset requested by the user (if one exists), but rather one + * required by the hardware (if required). + * + * MANUAL Tuning Policy: + * This variable equals the RF frequency in the tune request. */ + double target_rf_freq; - /*! The frequency to which the RF LO actually tuned - * - * If this does not equal the `target_rf_freq`, then it is because the - * target was outside of the range of the LO, or the LO was not able to - * hit it exactly due to tuning accuracy. */ - double actual_rf_freq; + /*! The frequency to which the RF LO actually tuned + * + * If this does not equal the `target_rf_freq`, then it is because the + * target was outside of the range of the LO, or the LO was not able to + * hit it exactly due to tuning accuracy. */ + double actual_rf_freq; - /*! The frequency the CORDIC must adjust the RF - * - * AUTO Tuning Policy: - * It is fairly common for the RF LO to not be able to exactly hit the - * requested frequency. This variable holds the required adjustment the - * CORDIC must make to the signal to bring it to the requested center - * frequency. - * - * MANUAL Tuning Policy - * This variable equals the DSP frequency in the tune request, clipped - * to be within range of the DSP if it was outside. */ - double target_dsp_freq; + /*! The frequency the CORDIC must adjust the RF + * + * AUTO Tuning Policy: + * It is fairly common for the RF LO to not be able to exactly hit the + * requested frequency. This variable holds the required adjustment the + * CORDIC must make to the signal to bring it to the requested center + * frequency. + * + * MANUAL Tuning Policy + * This variable equals the DSP frequency in the tune request, clipped + * to be within range of the DSP if it was outside. */ + double target_dsp_freq; - /*! The frequency to which the CORDIC in the DSP actually tuned - * - * If we failed to hit the target DSP frequency, it is either because - * the requested resolution wasn't possible or something went wrong in - * the DSP. In most cases, it should equal the `target_dsp_freq` above. - */ - double actual_dsp_freq; + /*! The frequency to which the CORDIC in the DSP actually tuned + * + * If we failed to hit the target DSP frequency, it is either because + * the requested resolution wasn't possible or something went wrong in + * the DSP. In most cases, it should equal the `target_dsp_freq` above. + */ + double actual_dsp_freq; - /*! - * Create a pretty print string for this tune result struct. - * \return the printable string - */ - std::string to_pp_string(void) const; - }; + /*! + * Create a pretty print string for this tune result struct. + * \return the printable string + */ + std::string to_pp_string(void) const; +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_TUNE_RESULT_HPP */ diff --git a/host/include/uhd/types/wb_iface.hpp b/host/include/uhd/types/wb_iface.hpp index 53c381c86..495762118 100644 --- a/host/include/uhd/types/wb_iface.hpp +++ b/host/include/uhd/types/wb_iface.hpp @@ -13,8 +13,7 @@ #include <stdint.h> #include <boost/shared_ptr.hpp> -namespace uhd -{ +namespace uhd { class UHD_API wb_iface { @@ -85,6 +84,6 @@ public: virtual void set_time(const time_spec_t& t) = 0; }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_TYPES_WB_IFACE_HPP */ diff --git a/host/include/uhd/usrp/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp index 9d885dfc0..8f9873399 100644 --- a/host/include/uhd/usrp/dboard_base.hpp +++ b/host/include/uhd/usrp/dboard_base.hpp @@ -9,20 +9,21 @@ #include <uhd/config.hpp> #include <uhd/property_tree.hpp> -#include <uhd/utils/pimpl.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/dboard_id.hpp> #include <uhd/usrp/dboard_iface.hpp> -#include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/utils/pimpl.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { /*! * A daughter board dboard_base class for all dboards. * Only other dboard dboard_base classes should inherit this. */ -class UHD_API dboard_base : boost::noncopyable{ +class UHD_API dboard_base : boost::noncopyable +{ public: typedef boost::shared_ptr<dboard_base> sptr; /*! @@ -30,13 +31,13 @@ public: * Derived classes should pass the args into the base class, * but should not deal with the internals of the args. */ - typedef void * ctor_args_t; + typedef void* ctor_args_t; - //structors + // structors dboard_base(ctor_args_t); virtual ~dboard_base() {} - //post-construction initializer + // post-construction initializer virtual void initialize() {} protected: @@ -57,7 +58,8 @@ private: * A xcvr daughter board implements rx and tx methods * Sub classes for xcvr boards should inherit this. */ -class UHD_API xcvr_dboard_base : public dboard_base{ +class UHD_API xcvr_dboard_base : public dboard_base +{ public: /*! * Create a new xcvr dboard object, override in subclasses. @@ -70,7 +72,8 @@ public: * A rx daughter board only implements rx methods. * Sub classes for rx-only boards should inherit this. */ -class UHD_API rx_dboard_base : public dboard_base{ +class UHD_API rx_dboard_base : public dboard_base +{ public: /*! * Create a new rx dboard object, override in subclasses. @@ -83,7 +86,8 @@ public: * A tx daughter board only implements tx methods. * Sub classes for rx-only boards should inherit this. */ -class UHD_API tx_dboard_base : public dboard_base{ +class UHD_API tx_dboard_base : public dboard_base +{ public: /*! * Create a new rx dboard object, override in subclasses. @@ -92,6 +96,6 @@ public: virtual ~tx_dboard_base() {} }; -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_DBOARD_BASE_HPP */ diff --git a/host/include/uhd/usrp/dboard_eeprom.hpp b/host/include/uhd/usrp/dboard_eeprom.hpp index 407d3f886..09d220bb3 100644 --- a/host/include/uhd/usrp/dboard_eeprom.hpp +++ b/host/include/uhd/usrp/dboard_eeprom.hpp @@ -9,14 +9,14 @@ #define INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP #include <uhd/config.hpp> -#include <uhd/usrp/dboard_id.hpp> #include <uhd/types/serial.hpp> +#include <uhd/usrp/dboard_id.hpp> #include <string> -namespace uhd{ namespace usrp{ - -struct UHD_API dboard_eeprom_t{ +namespace uhd { namespace usrp { +struct UHD_API dboard_eeprom_t +{ //! The ID for the daughterboard type dboard_id_t id; @@ -36,17 +36,16 @@ struct UHD_API dboard_eeprom_t{ * \param iface the serial interface with i2c * \param addr the i2c address for the eeprom */ - void load(i2c_iface &iface, uint8_t addr); + void load(i2c_iface& iface, uint8_t addr); /*! * Store the object to bytes in the eeprom. * \param iface the serial interface with i2c * \param addr the i2c address for the eeprom */ - void store(i2c_iface &iface, uint8_t addr) const; - + void store(i2c_iface& iface, uint8_t addr) const; }; -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP */ diff --git a/host/include/uhd/usrp/dboard_id.hpp b/host/include/uhd/usrp/dboard_id.hpp index 76c9c190b..2b48b0e46 100644 --- a/host/include/uhd/usrp/dboard_id.hpp +++ b/host/include/uhd/usrp/dboard_id.hpp @@ -13,74 +13,75 @@ #include <boost/operators.hpp> #include <string> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - class UHD_API dboard_id_t : boost::equality_comparable<dboard_id_t>{ - public: - /*! - * Create a dboard id from an integer. - * \param id the integer representation - */ - dboard_id_t(uint16_t id = 0xffff); - - /*! - * Obtain a dboard id that represents no dboard. - * \return the dboard id with the 0xffff id. - */ - static dboard_id_t none(void); - - /*! - * Create a new dboard id from an integer representation. - * \param uint16 an unsigned 16 bit integer - * \return a new dboard id containing the integer - */ - static dboard_id_t from_uint16(uint16_t uint16); +class UHD_API dboard_id_t : boost::equality_comparable<dboard_id_t> +{ +public: + /*! + * Create a dboard id from an integer. + * \param id the integer representation + */ + dboard_id_t(uint16_t id = 0xffff); - /*! - * Get the dboard id represented as an integer. - * \return an unsigned 16 bit integer representation - */ - uint16_t to_uint16(void) const; + /*! + * Obtain a dboard id that represents no dboard. + * \return the dboard id with the 0xffff id. + */ + static dboard_id_t none(void); - /*! - * Create a new dboard id from a string representation. - * If the string has a 0x prefix, it will be parsed as hex. - * \param string a numeric string, possibly hex - * \return a new dboard id containing the integer - */ - static dboard_id_t from_string(const std::string &string); + /*! + * Create a new dboard id from an integer representation. + * \param uint16 an unsigned 16 bit integer + * \return a new dboard id containing the integer + */ + static dboard_id_t from_uint16(uint16_t uint16); - /*! - * Get the dboard id represented as an integer. - * \return a hex string representation with 0x prefix - */ - std::string to_string(void) const; + /*! + * Get the dboard id represented as an integer. + * \return an unsigned 16 bit integer representation + */ + uint16_t to_uint16(void) const; - /*! - * Get the dboard id represented as a canonical name. - * \return the canonical string representation - */ - std::string to_cname(void) const; + /*! + * Create a new dboard id from a string representation. + * If the string has a 0x prefix, it will be parsed as hex. + * \param string a numeric string, possibly hex + * \return a new dboard id containing the integer + */ + static dboard_id_t from_string(const std::string& string); - /*! - * Get the pretty print representation of this dboard id. - * \return a string with the dboard name and id number - */ - std::string to_pp_string(void) const; + /*! + * Get the dboard id represented as an integer. + * \return a hex string representation with 0x prefix + */ + std::string to_string(void) const; - private: - uint16_t _id; //internal representation - }; + /*! + * Get the dboard id represented as a canonical name. + * \return the canonical string representation + */ + std::string to_cname(void) const; /*! - * Comparator operator overloaded for dboard ids. - * The boost::equality_comparable provides the !=. - * \param lhs the dboard id to the left of the operator - * \param rhs the dboard id to the right of the operator - * \return true when the dboard ids are equal + * Get the pretty print representation of this dboard id. + * \return a string with the dboard name and id number */ - UHD_API bool operator==(const dboard_id_t &lhs, const dboard_id_t &rhs); + std::string to_pp_string(void) const; + +private: + uint16_t _id; // internal representation +}; + +/*! + * Comparator operator overloaded for dboard ids. + * The boost::equality_comparable provides the !=. + * \param lhs the dboard id to the left of the operator + * \param rhs the dboard id to the right of the operator + * \return true when the dboard ids are equal + */ +UHD_API bool operator==(const dboard_id_t& lhs, const dboard_id_t& rhs); -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_DBOARD_ID_HPP */ diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp index 60b1954fc..162d0c6a3 100644 --- a/host/include/uhd/usrp/dboard_iface.hpp +++ b/host/include/uhd/usrp/dboard_iface.hpp @@ -9,21 +9,22 @@ #define INCLUDED_UHD_USRP_DBOARD_IFACE_HPP #include <uhd/config.hpp> -#include <uhd/utils/pimpl.hpp> #include <uhd/types/serial.hpp> #include <uhd/types/time_spec.hpp> #include <uhd/usrp/fe_connection.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <boost/shared_ptr.hpp> +#include <uhd/utils/pimpl.hpp> #include <stdint.h> +#include <boost/shared_ptr.hpp> #include <boost/thread/thread.hpp> #include <string> #include <vector> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { //! Special properties that differentiate this daughterboard slot -struct UHD_API dboard_iface_special_props_t{ +struct UHD_API dboard_iface_special_props_t +{ /*! * Soft clock divider: * When a motherboard cannot provided a divided dboard clock, @@ -49,20 +50,21 @@ struct UHD_API dboard_iface_special_props_t{ * This interface provides i2c, spi, gpio, atr, aux dac/adc access. * Each mboard should have a specially tailored iface for its dboard. */ -class UHD_API dboard_iface : public uhd::i2c_iface{ +class UHD_API dboard_iface : public uhd::i2c_iface +{ public: typedef boost::shared_ptr<dboard_iface> sptr; typedef dboard_iface_special_props_t special_props_t; //! tells the host which unit to use - enum unit_t{ + enum unit_t { UNIT_RX = int('r'), UNIT_TX = int('t'), UNIT_BOTH = int('b'), }; //! aux dac selection enums (per unit) - enum aux_dac_t{ + enum aux_dac_t { AUX_DAC_A = int('a'), AUX_DAC_B = int('b'), AUX_DAC_C = int('c'), @@ -70,14 +72,11 @@ public: }; //! aux adc selection enums (per unit) - enum aux_adc_t{ - AUX_ADC_A = int('a'), - AUX_ADC_B = int('b') - }; + enum aux_adc_t { AUX_ADC_A = int('a'), AUX_ADC_B = int('b') }; typedef uhd::usrp::gpio_atr::gpio_atr_reg_t atr_reg_t; - virtual ~dboard_iface(void) {}; + virtual ~dboard_iface(void){}; /*! * Get special properties information for this dboard slot. @@ -112,9 +111,7 @@ public: * \param value 16-bits, 0=GPIO controlled, 1=ATR controlled * \param mask 16-bits, 0=do not change, 1=change value */ - virtual void set_pin_ctrl( - unit_t unit, uint32_t value, uint32_t mask = 0xffff - ) = 0; + virtual void set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask = 0xffff) = 0; /*! * Read back the pin control setting. @@ -133,8 +130,7 @@ public: * \param mask 16-bits, 0=do not change, 1=change value */ virtual void set_atr_reg( - unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffff - ) = 0; + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffff) = 0; /*! * Read back an ATR register setting. @@ -152,9 +148,7 @@ public: * \param value 16-bits, 0=GPIO input, 1=GPIO output * \param mask 16-bits, 0=do not change, 1=change value */ - virtual void set_gpio_ddr( - unit_t unit, uint32_t value, uint32_t mask = 0xffff - ) = 0; + virtual void set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask = 0xffff) = 0; /*! * Read back the GPIO data direction setting. @@ -171,9 +165,7 @@ public: * \param value 16-bits, 0=GPIO output low, 1=GPIO output high * \param mask 16-bits, 0=do not change, 1=change value */ - virtual void set_gpio_out( - unit_t unit, uint32_t value, uint32_t mask = 0xffff - ) = 0; + virtual void set_gpio_out(unit_t unit, uint32_t value, uint32_t mask = 0xffff) = 0; /*! * Read back the GPIO pin output setting. @@ -200,11 +192,7 @@ public: * \param num_bits the number of bits in data */ virtual void write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ) = 0; + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) = 0; /*! * Read and write data to SPI bus peripheral. @@ -216,11 +204,7 @@ public: * \return the data that was read */ virtual uint32_t read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits - ) = 0; + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) = 0; /*! * Set the rate of a dboard clock. @@ -270,15 +254,16 @@ public: * \param fe_name name of the front-end to update * \param fe_conn connection parameters class */ - virtual void set_fe_connection( - unit_t unit, + virtual void set_fe_connection(unit_t unit, const std::string& fe_name, - const uhd::usrp::fe_connection_t& fe_conn - ) = 0; + const uhd::usrp::fe_connection_t& fe_conn) = 0; /*! Returns the true if set_fe_connection() is implemented on this dboard_iface */ - virtual bool has_set_fe_connection(const unit_t) { return false; } + virtual bool has_set_fe_connection(const unit_t) + { + return false; + } /*! * Get the command time. @@ -299,6 +284,6 @@ public: virtual void sleep(const boost::chrono::nanoseconds& time); }; -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_DBOARD_IFACE_HPP */ diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp index 9b9384fa8..cda1127fb 100644 --- a/host/include/uhd/usrp/dboard_manager.hpp +++ b/host/include/uhd/usrp/dboard_manager.hpp @@ -10,62 +10,61 @@ #include <uhd/config.hpp> #include <uhd/property_tree.hpp> #include <uhd/usrp/dboard_base.hpp> -#include <uhd/usrp/dboard_id.hpp> #include <uhd/usrp/dboard_eeprom.hpp> -#include <boost/utility.hpp> +#include <uhd/usrp/dboard_id.hpp> #include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> #include <string> #include <vector> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { /*! * A daughter board subdev dboard_manager class. * Create subdev instances for each subdev on a dboard. * Provide wax::obj access to the subdevs inside. */ -class UHD_API dboard_manager : boost::noncopyable{ +class UHD_API dboard_manager : boost::noncopyable +{ public: typedef boost::shared_ptr<dboard_manager> sptr; - //dboard constructor (each dboard should have a ::make with this signature) - typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t); + // dboard constructor (each dboard should have a ::make with this signature) + typedef dboard_base::sptr (*dboard_ctor_t)(dboard_base::ctor_args_t); /*! * Register a rx or tx dboard into the system. * For single subdevice boards, omit subdev_names. * \param dboard_id the dboard id (rx or tx) - * \param db_subdev_ctor the dboard sub-device constructor function pointer (one instance per subdev name) - * \param name the canonical name for the dboard represented + * \param db_subdev_ctor the dboard sub-device constructor function pointer (one + * instance per subdev name) \param name the canonical name for the dboard represented * \param subdev_names the names of the subdevs on this dboard - * \param db_container_ctor the dboard container constructor function pointer (one instance per dboard) + * \param db_container_ctor the dboard container constructor function pointer (one + * instance per dboard) */ - static void register_dboard( - const dboard_id_t &dboard_id, + static void register_dboard(const dboard_id_t& dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names = std::vector<std::string>(1, "0"), - dboard_ctor_t db_container_ctor = NULL - ); + const std::string& name, + const std::vector<std::string>& subdev_names = std::vector<std::string>(1, "0"), + dboard_ctor_t db_container_ctor = NULL); /*! * Register an xcvr dboard into the system. * For single subdevice boards, omit subdev_names. * \param rx_dboard_id the rx unit dboard id * \param tx_dboard_id the tx unit dboard id - * \param db_subdev_ctor the dboard sub-device constructor function pointer (one instance per subdev name) - * \param name the canonical name for the dboard represented + * \param db_subdev_ctor the dboard sub-device constructor function pointer (one + * instance per subdev name) \param name the canonical name for the dboard represented * \param subdev_names the names of the subdevs on this dboard - * \param db_container_ctor the dboard container constructor function pointer (one instance per dboard) + * \param db_container_ctor the dboard container constructor function pointer (one + * instance per dboard) */ - static void register_dboard( - const dboard_id_t &rx_dboard_id, - const dboard_id_t &tx_dboard_id, + static void register_dboard(const dboard_id_t& rx_dboard_id, + const dboard_id_t& tx_dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names = std::vector<std::string>(1, "0"), - dboard_ctor_t db_container_ctor = NULL - ); + const std::string& name, + const std::vector<std::string>& subdev_names = std::vector<std::string>(1, "0"), + dboard_ctor_t db_container_ctor = NULL); /*! * Register a restricted rx or tx dboard into the system. @@ -73,18 +72,17 @@ public: * For single subdevice boards, omit subdev_names. * The iface for a restricted board is not registered into the property tree. * \param dboard_id the dboard id (rx or tx) - * \param db_subdev_ctor the dboard sub-device constructor function pointer (one instance per subdev name) - * \param name the canonical name for the dboard represented + * \param db_subdev_ctor the dboard sub-device constructor function pointer (one + * instance per subdev name) \param name the canonical name for the dboard represented * \param subdev_names the names of the subdevs on this dboard - * \param db_container_ctor the dboard container constructor function pointer (one instance per dboard) + * \param db_container_ctor the dboard container constructor function pointer (one + * instance per dboard) */ - static void register_dboard_restricted( - const dboard_id_t &dboard_id, + static void register_dboard_restricted(const dboard_id_t& dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names = std::vector<std::string>(1, "0"), - dboard_ctor_t db_container_ctor = NULL - ); + const std::string& name, + const std::vector<std::string>& subdev_names = std::vector<std::string>(1, "0"), + dboard_ctor_t db_container_ctor = NULL); /*! * Register a restricted xcvr dboard into the system. @@ -93,19 +91,18 @@ public: * The iface for a restricted board is not registered into the property tree. * \param rx_dboard_id the rx unit dboard id * \param tx_dboard_id the tx unit dboard id - * \param db_subdev_ctor the dboard sub-device constructor function pointer (one instance per subdev name) - * \param name the canonical name for the dboard represented + * \param db_subdev_ctor the dboard sub-device constructor function pointer (one + * instance per subdev name) \param name the canonical name for the dboard represented * \param subdev_names the names of the subdevs on this dboard - * \param db_container_ctor the dboard container constructor function pointer (one instance per dboard) + * \param db_container_ctor the dboard container constructor function pointer (one + * instance per dboard) */ - static void register_dboard_restricted( - const dboard_id_t &rx_dboard_id, - const dboard_id_t &tx_dboard_id, + static void register_dboard_restricted(const dboard_id_t& rx_dboard_id, + const dboard_id_t& tx_dboard_id, dboard_ctor_t db_subdev_ctor, - const std::string &name, - const std::vector<std::string> &subdev_names = std::vector<std::string>(1, "0"), - dboard_ctor_t db_container_ctor = NULL - ); + const std::string& name, + const std::vector<std::string>& subdev_names = std::vector<std::string>(1, "0"), + dboard_ctor_t db_container_ctor = NULL); /*! * Make a new dboard manager. @@ -117,14 +114,12 @@ public: * \param defer_db_init initialising the daughterboards (DEPRECATED) * \return an sptr to the new dboard manager */ - static sptr make( - dboard_id_t rx_dboard_id, + static sptr make(dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, dboard_id_t gdboard_id, dboard_iface::sptr iface, property_tree::sptr subtree, - bool defer_db_init = false - ); + bool defer_db_init = false); /*! * Make a new dboard manager. @@ -136,14 +131,12 @@ public: * \param defer_db_init initialising the daughterboards (DEPRECATED) * \return an sptr to the new dboard manager */ - static sptr make( - dboard_eeprom_t rx_eeprom, + static sptr make(dboard_eeprom_t rx_eeprom, dboard_eeprom_t tx_eeprom, dboard_eeprom_t gdb_eeprom, dboard_iface::sptr iface, property_tree::sptr subtree, - bool defer_db_init = false - ); + bool defer_db_init = false); virtual ~dboard_manager() {} @@ -165,6 +158,6 @@ public: virtual const std::vector<std::string>& get_tx_frontends() const = 0; }; -}} //namespace +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP */ diff --git a/host/include/uhd/usrp/fe_connection.hpp b/host/include/uhd/usrp/fe_connection.hpp index d2050bb0f..0b34af40d 100644 --- a/host/include/uhd/usrp/fe_connection.hpp +++ b/host/include/uhd/usrp/fe_connection.hpp @@ -14,104 +14,114 @@ namespace uhd { namespace usrp { - class UHD_API fe_connection_t : boost::equality_comparable<fe_connection_t> { - public: - /** Sampling mode. - * Represents the sampling architecture for the front-end - */ - enum sampling_t { - QUADRATURE, /**< Complex sampling (Complex input, Complex output). */ - HETERODYNE, /**< Heterodyne sampling (Real input, Complex output). Only one of the I and Q inputs is used. */ - REAL /**< Real sampling (Real input, Real output). Only one of the I and Q inputs is used. */ - }; - - /*! - * Create a frontend connection class from individual settings. - * \param sampling_mode can be { QUADRATURE, HETERODYNE, REAL } - * \param iq_swapped indicates if the IQ channels are swapped (after inverion and heterodyne correction) - * \param i_inverted indicates if the I channel is inverted (negated) - * \param q_inverted indicates if the Q channel is inverted (negated) - * \param if_freq the baseband sampling frequency. - */ - fe_connection_t( - sampling_t sampling_mode, bool iq_swapped, - bool i_inverted, bool q_inverted, double if_freq = 0.0 - ); - - /*! - * Create a frontend connection class from a connection string - * The connection string can be: - * - in {I, Q}: Real mode sampling with no inversion. - * - in {Ib, Qb}: Real mode sampling with inversion. - * - in {IQ, QI}: Quadrature sampling with no inversion. - * - in {IbQb, QbIb}: Quadrature sampling with inversion. - * - in {II, QQ}: Heterodyne sampling with no inversion. - * - in {IbIb, QbQb}: Heterodyne sampling with inversion. - * - * \param conn_str the connection string. - * \param if_freq the baseband sampling frequency. - */ - fe_connection_t(const std::string& conn_str, double if_freq = 0.0); - - /*! - * Accessor for sampling mode - */ - inline sampling_t get_sampling_mode() const { - return _sampling_mode; - } - - /*! - * Accessor for IQ swap parameter - */ - inline bool is_iq_swapped() const { - return _iq_swapped; - } - - /*! - * Accessor for I inversion parameter - */ - inline bool is_i_inverted() const { - return _i_inverted; - } - - /*! - * Accessor for Q inversion parameter - */ - inline bool is_q_inverted() const { - return _q_inverted; - } - - /*! - * Accessor for IF frequency - */ - inline double get_if_freq() const { - return _if_freq; - } - - /*! - * Mutator for IF frequency - */ - inline void set_if_freq(double freq) { - _if_freq = freq; - } - - private: - sampling_t _sampling_mode; - bool _iq_swapped; - bool _i_inverted; - bool _q_inverted; - double _if_freq; +class UHD_API fe_connection_t : boost::equality_comparable<fe_connection_t> +{ +public: + /** Sampling mode. + * Represents the sampling architecture for the front-end + */ + enum sampling_t { + QUADRATURE, /**< Complex sampling (Complex input, Complex output). */ + HETERODYNE, /**< Heterodyne sampling (Real input, Complex output). Only one of the + I and Q inputs is used. */ + REAL /**< Real sampling (Real input, Real output). Only one of the I and Q inputs + is used. */ }; /*! - * Comparator operator overloaded for fe_connection_t. - * The boost::equality_comparable provides the !=. - * \param lhs the fe_connection_t to the left of the operator - * \param rhs the fe_connection_t to the right of the operator - * \return true when the fe connections are equal + * Create a frontend connection class from individual settings. + * \param sampling_mode can be { QUADRATURE, HETERODYNE, REAL } + * \param iq_swapped indicates if the IQ channels are swapped (after inverion and + * heterodyne correction) \param i_inverted indicates if the I channel is inverted + * (negated) \param q_inverted indicates if the Q channel is inverted (negated) \param + * if_freq the baseband sampling frequency. + */ + fe_connection_t(sampling_t sampling_mode, + bool iq_swapped, + bool i_inverted, + bool q_inverted, + double if_freq = 0.0); + + /*! + * Create a frontend connection class from a connection string + * The connection string can be: + * - in {I, Q}: Real mode sampling with no inversion. + * - in {Ib, Qb}: Real mode sampling with inversion. + * - in {IQ, QI}: Quadrature sampling with no inversion. + * - in {IbQb, QbIb}: Quadrature sampling with inversion. + * - in {II, QQ}: Heterodyne sampling with no inversion. + * - in {IbIb, QbQb}: Heterodyne sampling with inversion. + * + * \param conn_str the connection string. + * \param if_freq the baseband sampling frequency. */ - UHD_API bool operator==(const fe_connection_t &lhs, const fe_connection_t &rhs); + fe_connection_t(const std::string& conn_str, double if_freq = 0.0); -}} //namespace + /*! + * Accessor for sampling mode + */ + inline sampling_t get_sampling_mode() const + { + return _sampling_mode; + } + + /*! + * Accessor for IQ swap parameter + */ + inline bool is_iq_swapped() const + { + return _iq_swapped; + } + + /*! + * Accessor for I inversion parameter + */ + inline bool is_i_inverted() const + { + return _i_inverted; + } + + /*! + * Accessor for Q inversion parameter + */ + inline bool is_q_inverted() const + { + return _q_inverted; + } + + /*! + * Accessor for IF frequency + */ + inline double get_if_freq() const + { + return _if_freq; + } + + /*! + * Mutator for IF frequency + */ + inline void set_if_freq(double freq) + { + _if_freq = freq; + } + +private: + sampling_t _sampling_mode; + bool _iq_swapped; + bool _i_inverted; + bool _q_inverted; + double _if_freq; +}; + +/*! + * Comparator operator overloaded for fe_connection_t. + * The boost::equality_comparable provides the !=. + * \param lhs the fe_connection_t to the left of the operator + * \param rhs the fe_connection_t to the right of the operator + * \return true when the fe connections are equal + */ +UHD_API bool operator==(const fe_connection_t& lhs, const fe_connection_t& rhs); + +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_FE_CONNECTION_HPP */ diff --git a/host/include/uhd/usrp/gpio_defs.hpp b/host/include/uhd/usrp/gpio_defs.hpp index 65d6a761e..5cf09b496 100644 --- a/host/include/uhd/usrp/gpio_defs.hpp +++ b/host/include/uhd/usrp/gpio_defs.hpp @@ -10,13 +10,13 @@ namespace uhd { namespace usrp { namespace gpio_atr { - enum gpio_atr_reg_t { - ATR_REG_IDLE = int('i'), - ATR_REG_TX_ONLY = int('t'), - ATR_REG_RX_ONLY = int('r'), - ATR_REG_FULL_DUPLEX = int('f') - }; +enum gpio_atr_reg_t { + ATR_REG_IDLE = int('i'), + ATR_REG_TX_ONLY = int('t'), + ATR_REG_RX_ONLY = int('r'), + ATR_REG_FULL_DUPLEX = int('f') +}; -}}} //namespaces +}}} // namespace uhd::usrp::gpio_atr #endif /* INCLUDED_LIBUHD_USRP_GPIO_DEFS_HPP */ diff --git a/host/include/uhd/usrp/gps_ctrl.hpp b/host/include/uhd/usrp/gps_ctrl.hpp index 1e0d35b91..91d653759 100644 --- a/host/include/uhd/usrp/gps_ctrl.hpp +++ b/host/include/uhd/usrp/gps_ctrl.hpp @@ -8,46 +8,46 @@ #ifndef INCLUDED_GPS_CTRL_HPP #define INCLUDED_GPS_CTRL_HPP -#include <uhd/types/serial.hpp> #include <uhd/types/sensors.hpp> +#include <uhd/types/serial.hpp> +#include <boost/function.hpp> #include <boost/shared_ptr.hpp> #include <boost/utility.hpp> -#include <boost/function.hpp> #include <vector> -namespace uhd{ +namespace uhd { -class UHD_API gps_ctrl : boost::noncopyable{ +class UHD_API gps_ctrl : boost::noncopyable +{ public: - typedef boost::shared_ptr<gps_ctrl> sptr; - - virtual ~gps_ctrl(void) = 0; + typedef boost::shared_ptr<gps_ctrl> sptr; - /*! - * Make a GPS config for internal GPSDOs or generic NMEA GPS devices - */ - static sptr make(uart_iface::sptr uart); + virtual ~gps_ctrl(void) = 0; - /*! - * Retrieve the list of sensors this GPS object provides - */ - virtual std::vector<std::string> get_sensors(void) = 0; + /*! + * Make a GPS config for internal GPSDOs or generic NMEA GPS devices + */ + static sptr make(uart_iface::sptr uart); - /*! - * Retrieve the named sensor - */ - virtual uhd::sensor_value_t get_sensor(std::string key) = 0; + /*! + * Retrieve the list of sensors this GPS object provides + */ + virtual std::vector<std::string> get_sensors(void) = 0; - /*! - * Tell you if there's a supported GPS connected or not - * \return true if a supported GPS is connected - */ - virtual bool gps_detected(void) = 0; + /*! + * Retrieve the named sensor + */ + virtual uhd::sensor_value_t get_sensor(std::string key) = 0; - //TODO: other fun things you can do with a GPS. + /*! + * Tell you if there's a supported GPS connected or not + * \return true if a supported GPS is connected + */ + virtual bool gps_detected(void) = 0; + // TODO: other fun things you can do with a GPS. }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_GPS_CTRL_HPP */ diff --git a/host/include/uhd/usrp/mboard_eeprom.hpp b/host/include/uhd/usrp/mboard_eeprom.hpp index 72efd7c99..fcc587e08 100644 --- a/host/include/uhd/usrp/mboard_eeprom.hpp +++ b/host/include/uhd/usrp/mboard_eeprom.hpp @@ -12,20 +12,20 @@ #include <uhd/types/dict.hpp> #include <string> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - /*! The motherboard EEPROM object. - * - * The specific implementation knows how to read and write the EEPROM for - * various USRPs. By itself, this class is nothing but a thin wrapper - * around a string -> string dictionary. - * - * Note that writing to an object of type mboard_eeprom_t does not actually - * write to the EEPROM. Devices have their own APIs to read/write from the - * EEPROM chips themselves. Most devices will write the EEPROM itself when - * the according property is updated. - */ - typedef uhd::dict<std::string, std::string> mboard_eeprom_t; +/*! The motherboard EEPROM object. + * + * The specific implementation knows how to read and write the EEPROM for + * various USRPs. By itself, this class is nothing but a thin wrapper + * around a string -> string dictionary. + * + * Note that writing to an object of type mboard_eeprom_t does not actually + * write to the EEPROM. Devices have their own APIs to read/write from the + * EEPROM chips themselves. Most devices will write the EEPROM itself when + * the according property is updated. + */ +typedef uhd::dict<std::string, std::string> mboard_eeprom_t; }} // namespace uhd::usrp diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 71b2a1161..a99cba845 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -8,7 +8,7 @@ #ifndef INCLUDED_UHD_USRP_MULTI_USRP_HPP #define INCLUDED_UHD_USRP_MULTI_USRP_HPP -//define API capabilities for compile time detection of new features +// define API capabilities for compile time detection of new features #define UHD_USRP_MULTI_USRP_REF_SOURCES_API #define UHD_USRP_MULTI_USRP_GET_RATES_API #define UHD_USRP_MULTI_USRP_FRONTEND_CAL_API @@ -25,17 +25,17 @@ #define UHD_USRP_MULTI_USRP_TX_LO_CONFIG_API #include <uhd/config.hpp> -#include <uhd/device.hpp> #include <uhd/deprecated.hpp> +#include <uhd/device.hpp> +#include <uhd/types/filters.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/sensors.hpp> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/tune_request.hpp> #include <uhd/types/tune_result.hpp> -#include <uhd/types/sensors.hpp> -#include <uhd/types/filters.hpp> #include <uhd/types/wb_iface.hpp> -#include <uhd/usrp/subdev_spec.hpp> #include <uhd/usrp/dboard_iface.hpp> +#include <uhd/usrp/subdev_spec.hpp> #include <boost/shared_ptr.hpp> #include <boost/utility.hpp> #include <complex> @@ -43,9 +43,9 @@ #include <vector> namespace uhd { - class device3; +class device3; - namespace usrp{ +namespace usrp { /*! * The Multi-USRP device class: @@ -93,7 +93,8 @@ namespace uhd { * * </pre> */ -class UHD_API multi_usrp : boost::noncopyable{ +class UHD_API multi_usrp : boost::noncopyable +{ public: typedef boost::shared_ptr<multi_usrp> sptr; @@ -118,7 +119,7 @@ public: * \throws uhd::key_error no device found * \throws uhd::index_error fewer devices found than expected */ - static sptr make(const device_addr_t &dev_addr); + static sptr make(const device_addr_t& dev_addr); /*! * Get the underlying device object. @@ -142,10 +143,10 @@ public: virtual boost::shared_ptr<uhd::device3> get_device3(void) = 0; //! Convenience method to get a RX streamer. See also uhd::device::get_rx_stream(). - virtual rx_streamer::sptr get_rx_stream(const stream_args_t &args) = 0; + virtual rx_streamer::sptr get_rx_stream(const stream_args_t& args) = 0; //! Convenience method to get a TX streamer. See also uhd::device::get_tx_stream(). - virtual tx_streamer::sptr get_tx_stream(const stream_args_t &args) = 0; + virtual tx_streamer::sptr get_tx_stream(const stream_args_t& args) = 0; /*! * Returns identifying information about this USRP's configuration. @@ -163,7 +164,7 @@ public: * \param chan channel index 0 to N-1 * \return TX info */ - virtual dict<std::string, std::string> get_usrp_tx_info(size_t chan = 0) = 0; + virtual dict<std::string, std::string> get_usrp_tx_info(size_t chan = 0) = 0; /******************************************************************* * Mboard methods @@ -258,7 +259,8 @@ public: * \param time_spec the time to latch into the usrp device * \param mboard the motherboard index 0 to M-1 */ - virtual void set_time_now(const time_spec_t &time_spec, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_time_now( + const time_spec_t& time_spec, size_t mboard = ALL_MBOARDS) = 0; /*! * Set the time registers on the usrp at the next pps tick. @@ -272,7 +274,8 @@ public: * \param time_spec the time to latch into the usrp device * \param mboard the motherboard index 0 to M-1 */ - virtual void set_time_next_pps(const time_spec_t &time_spec, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_time_next_pps( + const time_spec_t& time_spec, size_t mboard = ALL_MBOARDS) = 0; /*! * Synchronize the times across all motherboards in this configuration. @@ -289,7 +292,7 @@ public: * * \param time_spec the time to latch at the next pps after catching the edge */ - virtual void set_time_unknown_pps(const time_spec_t &time_spec) = 0; + virtual void set_time_unknown_pps(const time_spec_t& time_spec) = 0; /*! * Are the times across all motherboards in this configuration synchronized? @@ -309,7 +312,8 @@ public: * \param time_spec the time at which the next command will activate * \param mboard which motherboard to set the config */ - virtual void set_command_time(const uhd::time_spec_t &time_spec, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_command_time( + const uhd::time_spec_t& time_spec, size_t mboard = ALL_MBOARDS) = 0; /*! * Clear the command time so future commands are sent ASAP. @@ -330,7 +334,8 @@ public: * \param stream_cmd the stream command to issue * \param chan the channel index 0 to N-1 */ - virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan = ALL_CHANS) = 0; + virtual void issue_stream_cmd( + const stream_cmd_t& stream_cmd, size_t chan = ALL_CHANS) = 0; /*! * Set the clock configuration for the usrp device. @@ -340,7 +345,8 @@ public: * \param clock_config the clock configuration to set * \param mboard which motherboard to set the config */ - virtual void set_clock_config(const clock_config_t &clock_config, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_clock_config( + const clock_config_t& clock_config, size_t mboard = ALL_MBOARDS) = 0; /*! Set the time source for the USRP device * @@ -385,9 +391,7 @@ public: * \throws uhd::value_error if \p source is an invalid option */ virtual void set_time_source( - const std::string &source, - const size_t mboard = ALL_MBOARDS - ) = 0; + const std::string& source, const size_t mboard = ALL_MBOARDS) = 0; /*! * Get the currently set time source. @@ -446,9 +450,7 @@ public: * \throws uhd::value_error if \p source is an invalid option */ virtual void set_clock_source( - const std::string &source, - const size_t mboard = ALL_MBOARDS - ) = 0; + const std::string& source, const size_t mboard = ALL_MBOARDS) = 0; /*! * Get the currently set clock source. @@ -474,11 +476,9 @@ public: * \param mboard which motherboard to set the config * \throws uhd::value_error if the sources don't actually exist */ - virtual void set_sync_source( - const std::string &clock_source, - const std::string &time_source, - const size_t mboard = ALL_MBOARDS - ) = 0; + virtual void set_sync_source(const std::string& clock_source, + const std::string& time_source, + const size_t mboard = ALL_MBOARDS) = 0; /*! Set the reference/synchronization sources for the USRP device * @@ -503,9 +503,7 @@ public: * combination of clock and time source is invalid. */ virtual void set_sync_source( - const device_addr_t& sync_source, - const size_t mboard = ALL_MBOARDS - ) = 0; + const device_addr_t& sync_source, const size_t mboard = ALL_MBOARDS) = 0; /*! Get the currently set sync source. * @@ -529,7 +527,8 @@ public: * \param enb true to output the clock source. * \param mboard which motherboard to set */ - virtual void set_clock_source_out(const bool enb, const size_t mboard = ALL_MBOARDS) = 0; + virtual void set_clock_source_out( + const bool enb, const size_t mboard = ALL_MBOARDS) = 0; /*! * Send the time source to an output connector. @@ -539,7 +538,8 @@ public: * \param enb true to output the time source. * \param mboard which motherboard to set */ - virtual void set_time_source_out(const bool enb, const size_t mboard = ALL_MBOARDS) = 0; + virtual void set_time_source_out( + const bool enb, const size_t mboard = ALL_MBOARDS) = 0; /*! * Get the number of USRP motherboards in this configuration. @@ -552,7 +552,8 @@ public: * \param mboard the motherboard index 0 to M-1 * \return a sensor value object */ - virtual sensor_value_t get_mboard_sensor(const std::string &name, size_t mboard = 0) = 0; + virtual sensor_value_t get_mboard_sensor( + const std::string& name, size_t mboard = 0) = 0; /*! * Get a list of possible motherboard sensor names. @@ -568,7 +569,8 @@ public: * \param data 32-bit register value * \param mboard which motherboard to set the user register */ - virtual void set_user_register(const uint8_t addr, const uint32_t data, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_user_register( + const uint8_t addr, const uint32_t data, size_t mboard = ALL_MBOARDS) = 0; /*! Return a user settings interface object * @@ -607,7 +609,8 @@ public: * \param spec the new frontend specification * \param mboard the motherboard index 0 to M-1 */ - virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_rx_subdev_spec( + const uhd::usrp::subdev_spec_t& spec, size_t mboard = ALL_MBOARDS) = 0; /*! * Get the RX frontend specification. @@ -658,8 +661,7 @@ public: * \return a tune result object */ virtual tune_result_t set_rx_freq( - const tune_request_t &tune_request, size_t chan = 0 - ) = 0; + const tune_request_t& tune_request, size_t chan = 0) = 0; /*! * Get the RX center frequency. @@ -716,10 +718,7 @@ public: * \param chan the channel index 0 to N-1 */ virtual void set_rx_lo_source( - const std::string &src, - const std::string &name = ALL_LOS, - size_t chan = 0 - ) = 0; + const std::string& src, const std::string& name = ALL_LOS, size_t chan = 0) = 0; /*! Get the currently selected LO source. * @@ -730,9 +729,7 @@ public: * \return the configured LO source */ virtual const std::string get_rx_lo_source( - const std::string &name = ALL_LOS, - size_t chan = 0 - ) = 0; + const std::string& name = ALL_LOS, size_t chan = 0) = 0; /*! Get a list of possible LO sources. * @@ -746,9 +743,7 @@ public: * \return a vector of strings for possible settings */ virtual std::vector<std::string> get_rx_lo_sources( - const std::string &name = ALL_LOS, - size_t chan = 0 - ) = 0; + const std::string& name = ALL_LOS, size_t chan = 0) = 0; /*! Set whether the LO used by the device is exported * @@ -761,10 +756,7 @@ public: * \throws uhd::runtime_error if LO exporting is not enabled */ virtual void set_rx_lo_export_enabled( - bool enabled, - const std::string &name = ALL_LOS, - size_t chan = 0 - ) = 0; + bool enabled, const std::string& name = ALL_LOS, size_t chan = 0) = 0; /*! Returns true if the currently selected LO is being exported. * @@ -772,9 +764,7 @@ public: * \param chan the channel index 0 to N-1 */ virtual bool get_rx_lo_export_enabled( - const std::string &name = ALL_LOS, - size_t chan = 0 - ) = 0; + const std::string& name = ALL_LOS, size_t chan = 0) = 0; /*! Set the RX LO frequency (Advanced). * @@ -800,10 +790,7 @@ public: * \return a coerced LO frequency */ virtual double set_rx_lo_freq( - double freq, - const std::string &name, - size_t chan = 0 - ) = 0; + double freq, const std::string& name, size_t chan = 0) = 0; /*! Get the current RX LO frequency (Advanced). * @@ -815,10 +802,7 @@ public: * \param chan the channel index 0 to N-1 * \return the configured LO frequency */ - virtual double get_rx_lo_freq( - const std::string &name, - size_t chan = 0 - ) = 0; + virtual double get_rx_lo_freq(const std::string& name, size_t chan = 0) = 0; /*! Get the LO frequency range of the RX LO. * @@ -830,9 +814,7 @@ public: * \return a frequency range object */ virtual freq_range_t get_rx_lo_freq_range( - const std::string &name, - size_t chan = 0 - ) = 0; + const std::string& name, size_t chan = 0) = 0; /*! Get a list of possible TX LO stage names * @@ -859,11 +841,9 @@ public: * this channel. * \param chan the channel index 0 to N-1 */ - virtual void set_tx_lo_source( - const std::string &src, - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) = 0; + virtual void set_tx_lo_source(const std::string& src, + const std::string& name = ALL_LOS, + const size_t chan = 0) = 0; /*! Get the currently selected TX LO source. * @@ -874,9 +854,7 @@ public: * \return the configured LO source */ virtual const std::string get_tx_lo_source( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) = 0; + const std::string& name = ALL_LOS, const size_t chan = 0) = 0; /*! Get a list of possible LO sources. * @@ -889,9 +867,7 @@ public: * \return a vector of strings for possible settings */ virtual std::vector<std::string> get_tx_lo_sources( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) = 0; + const std::string& name = ALL_LOS, const size_t chan = 0) = 0; /*! Set whether the TX LO used by the device is exported * @@ -904,10 +880,7 @@ public: * \throws uhd::runtime_error if LO exporting is not enabled */ virtual void set_tx_lo_export_enabled( - const bool enabled, - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) = 0; + const bool enabled, const std::string& name = ALL_LOS, const size_t chan = 0) = 0; /*! Returns true if the currently selected LO is being exported. * @@ -915,9 +888,7 @@ public: * \param chan the channel index 0 to N-1 */ virtual bool get_tx_lo_export_enabled( - const std::string &name = ALL_LOS, - const size_t chan = 0 - ) = 0; + const std::string& name = ALL_LOS, const size_t chan = 0) = 0; /*! Set the TX LO frequency (Advanced). * @@ -943,10 +914,7 @@ public: * \return a coerced LO frequency */ virtual double set_tx_lo_freq( - const double freq, - const std::string &name, - const size_t chan=0 - ) = 0; + const double freq, const std::string& name, const size_t chan = 0) = 0; /*! Get the current TX LO frequency (Advanced). * @@ -958,10 +926,7 @@ public: * \param chan the channel index 0 to N-1 * \return the configured LO frequency */ - virtual double get_tx_lo_freq( - const std::string &name, - const size_t chan=0 - ) = 0; + virtual double get_tx_lo_freq(const std::string& name, const size_t chan = 0) = 0; /*! Get the LO frequency range of the TX LO. * @@ -973,9 +938,7 @@ public: * \return a frequency range object */ virtual freq_range_t get_tx_lo_freq_range( - const std::string &name, - const size_t chan=0 - ) = 0; + const std::string& name, const size_t chan = 0) = 0; /************************************************************************** * Gain controls @@ -987,15 +950,15 @@ public: * \param name the name of the gain element * \param chan the channel index 0 to N-1 */ - virtual void set_rx_gain(double gain, const std::string &name, size_t chan = 0) = 0; + virtual void set_rx_gain(double gain, const std::string& name, size_t chan = 0) = 0; /*! Get a list of possible RX gain profile options * - * Example: On the TwinRX, this will return "low-noise", "low-distortion" or "default". - * These names can be used in gain-profile related API called. - * An empty return value doesn't mean there are no profile options, it means that - * this radio does not have any gain profiles implemented, and typically means - * there is only one default profile of set gain + * Example: On the TwinRX, this will return "low-noise", "low-distortion" or + * "default". These names can be used in gain-profile related API called. An empty + * return value doesn't mean there are no profile options, it means that this radio + * does not have any gain profiles implemented, and typically means there is only one + * default profile of set gain * * \param chan the channel index 0 to N-1 * \return a vector of strings for possible gain profile options, or an empty list of @@ -1008,7 +971,8 @@ public: * \param profile the profile string option * \param chan the channel index 0 to N-1 */ - virtual void set_rx_gain_profile(const std::string& profile, const size_t chan = 0) = 0; + virtual void set_rx_gain_profile( + const std::string& profile, const size_t chan = 0) = 0; /*! * Get the RX gain profile. @@ -1018,7 +982,8 @@ public: virtual std::string get_rx_gain_profile(const size_t chan = 0) = 0; //! A convenience wrapper for setting overall RX gain - void set_rx_gain(double gain, size_t chan = 0){ + void set_rx_gain(double gain, size_t chan = 0) + { return this->set_rx_gain(gain, ALL_GAINS, chan); } @@ -1043,8 +1008,8 @@ public: /*! * Enable or disable the RX AGC module. * Once this module is enabled manual gain settings will be ignored. - * The AGC will start in a default configuration which should be good for most use cases. - * Device specific configuration parameters can be found in the property tree. + * The AGC will start in a default configuration which should be good for most use + * cases. Device specific configuration parameters can be found in the property tree. * \param enable Enable or Disable the AGC * \param chan the channel index 0 to N-1 */ @@ -1057,10 +1022,11 @@ public: * \param chan the channel index 0 to N-1 * \return the gain in dB */ - virtual double get_rx_gain(const std::string &name, size_t chan = 0) = 0; + virtual double get_rx_gain(const std::string& name, size_t chan = 0) = 0; //! A convenience wrapper for getting overall RX gain - double get_rx_gain(size_t chan = 0){ + double get_rx_gain(size_t chan = 0) + { return this->get_rx_gain(ALL_GAINS, chan); } @@ -1083,10 +1049,11 @@ public: * \param chan the channel index 0 to N-1 * \return a gain range object */ - virtual gain_range_t get_rx_gain_range(const std::string &name, size_t chan = 0) = 0; + virtual gain_range_t get_rx_gain_range(const std::string& name, size_t chan = 0) = 0; //! A convenience wrapper for getting overall RX gain range - gain_range_t get_rx_gain_range(size_t chan = 0){ + gain_range_t get_rx_gain_range(size_t chan = 0) + { return this->get_rx_gain_range(ALL_GAINS, chan); } @@ -1103,7 +1070,7 @@ public: * \param ant the antenna name * \param chan the channel index 0 to N-1 */ - virtual void set_rx_antenna(const std::string &ant, size_t chan = 0) = 0; + virtual void set_rx_antenna(const std::string& ant, size_t chan = 0) = 0; /*! * Get the selected RX antenna on the frontend. @@ -1155,7 +1122,7 @@ public: * \param chan the channel index 0 to N-1 * \return a sensor value object */ - virtual sensor_value_t get_rx_sensor(const std::string &name, size_t chan = 0) = 0; + virtual sensor_value_t get_rx_sensor(const std::string& name, size_t chan = 0) = 0; /*! * Get a list of possible RX frontend sensor names. @@ -1185,7 +1152,8 @@ public: * \param offset the dc offset (1.0 is full-scale) * \param chan the channel index 0 to N-1 */ - virtual void set_rx_dc_offset(const std::complex<double> &offset, size_t chan = ALL_CHANS) = 0; + virtual void set_rx_dc_offset( + const std::complex<double>& offset, size_t chan = ALL_CHANS) = 0; /*! * Get the valid range for RX DC offset values. @@ -1208,7 +1176,8 @@ public: * \param correction the complex correction (1.0 is full-scale) * \param chan the channel index 0 to N-1 */ - virtual void set_rx_iq_balance(const std::complex<double> &correction, size_t chan = ALL_CHANS) = 0; + virtual void set_rx_iq_balance( + const std::complex<double>& correction, size_t chan = ALL_CHANS) = 0; /******************************************************************* * TX methods @@ -1221,7 +1190,8 @@ public: * \param spec the new frontend specification * \param mboard the motherboard index 0 to M-1 */ - virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0; + virtual void set_tx_subdev_spec( + const uhd::usrp::subdev_spec_t& spec, size_t mboard = ALL_MBOARDS) = 0; /*! * Get the TX frontend specification. @@ -1272,8 +1242,7 @@ public: * \return a tune result object */ virtual tune_result_t set_tx_freq( - const tune_request_t &tune_request, size_t chan = 0 - ) = 0; + const tune_request_t& tune_request, size_t chan = 0) = 0; /*! * Get the TX center frequency. @@ -1307,7 +1276,7 @@ public: * \param name the name of the gain element * \param chan the channel index 0 to N-1 */ - virtual void set_tx_gain(double gain, const std::string &name, size_t chan = 0) = 0; + virtual void set_tx_gain(double gain, const std::string& name, size_t chan = 0) = 0; /*! Get a list of possible TX gain profile options * @@ -1328,7 +1297,8 @@ public: * \param profile the profile string option * \param chan the channel index 0 to N-1 */ - virtual void set_tx_gain_profile(const std::string& profile, const size_t chan = 0) = 0; + virtual void set_tx_gain_profile( + const std::string& profile, const size_t chan = 0) = 0; /*! * Get the TX gain profile. @@ -1338,7 +1308,8 @@ public: virtual std::string get_tx_gain_profile(const size_t chan = 0) = 0; //! A convenience wrapper for setting overall TX gain - void set_tx_gain(double gain, size_t chan = 0){ + void set_tx_gain(double gain, size_t chan = 0) + { return this->set_tx_gain(gain, ALL_GAINS, chan); } @@ -1361,10 +1332,11 @@ public: * \param chan the channel index 0 to N-1 * \return the gain in dB */ - virtual double get_tx_gain(const std::string &name, size_t chan = 0) = 0; + virtual double get_tx_gain(const std::string& name, size_t chan = 0) = 0; //! A convenience wrapper for getting overall TX gain - double get_tx_gain(size_t chan = 0){ + double get_tx_gain(size_t chan = 0) + { return this->get_tx_gain(ALL_GAINS, chan); } @@ -1387,10 +1359,11 @@ public: * \param chan the channel index 0 to N-1 * \return a gain range object */ - virtual gain_range_t get_tx_gain_range(const std::string &name, size_t chan = 0) = 0; + virtual gain_range_t get_tx_gain_range(const std::string& name, size_t chan = 0) = 0; //! A convenience wrapper for getting overall TX gain range - gain_range_t get_tx_gain_range(size_t chan = 0){ + gain_range_t get_tx_gain_range(size_t chan = 0) + { return this->get_tx_gain_range(ALL_GAINS, chan); } @@ -1407,7 +1380,7 @@ public: * \param ant the antenna name * \param chan the channel index 0 to N-1 */ - virtual void set_tx_antenna(const std::string &ant, size_t chan = 0) = 0; + virtual void set_tx_antenna(const std::string& ant, size_t chan = 0) = 0; /*! * Get the selected TX antenna on the frontend. @@ -1459,7 +1432,7 @@ public: * \param chan the channel index 0 to N-1 * \return a sensor value object */ - virtual sensor_value_t get_tx_sensor(const std::string &name, size_t chan = 0) = 0; + virtual sensor_value_t get_tx_sensor(const std::string& name, size_t chan = 0) = 0; /*! * Get a list of possible TX frontend sensor names. @@ -1474,7 +1447,8 @@ public: * \param offset the dc offset (1.0 is full-scale) * \param chan the channel index 0 to N-1 */ - virtual void set_tx_dc_offset(const std::complex<double> &offset, size_t chan = ALL_CHANS) = 0; + virtual void set_tx_dc_offset( + const std::complex<double>& offset, size_t chan = ALL_CHANS) = 0; /*! * Get the valid range for TX DC offset values. @@ -1489,7 +1463,8 @@ public: * \param correction the complex correction (1.0 is full-scale) * \param chan the channel index 0 to N-1 */ - virtual void set_tx_iq_balance(const std::complex<double> &correction, size_t chan = ALL_CHANS) = 0; + virtual void set_tx_iq_balance( + const std::complex<double>& correction, size_t chan = ALL_CHANS) = 0; /******************************************************************* * GPIO methods @@ -1518,13 +1493,18 @@ public: * \param mask the bit mask to effect which pins are changed * \param mboard the motherboard index 0 to M-1 */ - virtual void set_gpio_attr(const std::string &bank, const std::string &attr, const uint32_t value, const uint32_t mask = 0xffffffff, const size_t mboard = 0) = 0; + virtual void set_gpio_attr(const std::string& bank, + const std::string& attr, + const uint32_t value, + const uint32_t mask = 0xffffffff, + const size_t mboard = 0) = 0; /*! * Set a GPIO attribute on a particular GPIO bank. * Possible attribute names: * - SRC - "PS" for handling by processing system - * - "RADIO_N/M" for handling by radio block with N is in [0..Number of Radio]; M is in [0..Number of port per Radio] + * - "RADIO_N/M" for handling by radio block with N is in [0..Number of + * Radio]; M is in [0..Number of port per Radio] * - CTRL - "ATR" for ATR mode * - "GPIO" for GPIO mode * - DDR - "OUT" for output @@ -1532,20 +1512,28 @@ public: * - OUT - a string of numbers representing GPIO output level (not ATR mode) * - "HIGH"or "LOW" as GPIO output level that apply for each bit mask that is 1 * - ATR_0X - a string of numbers representing a value of the ATR idle state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR idle state register - * - ATR_RX - a string of numbers representing a value of a ATR receive only state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR receive only state register - * - ATR_TX - a string of numbers representing a value of the ATR transmit only state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR transmit only state register - * - ATR_XX - a string of numbers representing a value of the ATR full duplex state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR full duplex state register - * \param bank the name of a GPIO bank - * \param attr the name of a GPIO attribute - * \param value the new value for this GPIO bank - * \param mask the bit mask to effect which pins are changed - * \param mboard the motherboard index 0 to M-1 - */ - virtual void set_gpio_attr(const std::string &bank, const std::string &attr, const std::string &value, const uint32_t mask = 0xffffffff, const size_t mboard = 0) = 0; + * - "HIGH" or "LOW" as a value set on each bit on of the ATR idle state + * register + * - ATR_RX - a string of numbers representing a value of a ATR receive only state + * register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR receive only + * state register + * - ATR_TX - a string of numbers representing a value of the ATR transmit only state + * register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR transmit only + * state register + * - ATR_XX - a string of numbers representing a value of the ATR full duplex state + * register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR full duplex + * state register \param bank the name of a GPIO bank \param attr the name of a GPIO + * attribute \param value the new value for this GPIO bank \param mask the bit mask to + * effect which pins are changed \param mboard the motherboard index 0 to M-1 + */ + virtual void set_gpio_attr(const std::string& bank, + const std::string& attr, + const std::string& value, + const uint32_t mask = 0xffffffff, + const size_t mboard = 0) = 0; /*! * Get a GPIO attribute on a particular GPIO bank. @@ -1563,13 +1551,15 @@ public: * \param mboard the motherboard index 0 to M-1 * \return the value set for this attribute */ - virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr, const size_t mboard = 0) = 0; + virtual uint32_t get_gpio_attr( + const std::string& bank, const std::string& attr, const size_t mboard = 0) = 0; /*! * Get a GPIO attribute on a particular GPIO bank. * Possible attribute names: * - SRC - "PS" for handling by processing system - * - "RADIO_N/M" for handling by radio block with N is in [0..Number of Radio]; M is in [0..Number of port per Radio] + * - "RADIO_N/M" for handling by radio block with N is in [0..Number of + * Radio]; M is in [0..Number of port per Radio] * - CTRL - "ATR" for ATR mode * - "GPIO" for GPIO mode * - DDR - "OUT" for output @@ -1577,25 +1567,34 @@ public: * - OUT - a string of numbers representing GPIO output level (not ATR mode) * - "HIGH"or "LOW" as GPIO output level that apply for each bit mask that is 1 * - ATR_0X - a string of numbers representing a value of the ATR idle state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR idle state register - * - ATR_RX - a string of numbers representing a value of a ATR receive only state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR receive only state register - * - ATR_TX - a string of numbers representing a value of the ATR transmit only state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR transmit only state register - * - ATR_XX - a string of numbers representing a value of the ATR full duplex state register - * - "HIGH" or "LOW" as a value set on each bit on of the ATR full duplex state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR idle state + * register + * - ATR_RX - a string of numbers representing a value of a ATR receive only state + * register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR receive only + * state register + * - ATR_TX - a string of numbers representing a value of the ATR transmit only state + * register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR transmit only + * state register + * - ATR_XX - a string of numbers representing a value of the ATR full duplex state + * register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR full duplex + * state register * - READBACK - readback input GPIOs * \param bank the name of a GPIO bank * \param attr the name of a GPIO attribute * \param mboard the motherboard index 0 to M-1 * \return the value set for this attribute in vector of strings */ - virtual std::vector<std::string> get_gpio_string_attr(const std::string &bank, const std::string &attr, const size_t mboard = 0) = 0; + virtual std::vector<std::string> get_gpio_string_attr( + const std::string& bank, const std::string& attr, const size_t mboard = 0) = 0; /******************************************************************* * Register IO methods ******************************************************************/ - struct register_info_t { + struct register_info_t + { size_t bitwidth; bool readable; bool writable; @@ -1612,18 +1611,23 @@ public: * Get more information about a low-level device register * \param path the full path to the register * \param mboard the motherboard index 0 to M-1 - * \return the info struct which contains the bitwidth and read-write access information + * \return the info struct which contains the bitwidth and read-write access + * information */ - virtual register_info_t get_register_info(const std::string &path, const size_t mboard = 0) = 0; + virtual register_info_t get_register_info( + const std::string& path, const size_t mboard = 0) = 0; /*! * Write a low-level register field for a register in the USRP hardware * \param path the full path to the register - * \param field the identifier of bitfield to be written (all other bits remain unchanged) - * \param value the value to write to the register field - * \param mboard the motherboard index 0 to M-1 + * \param field the identifier of bitfield to be written (all other bits remain + * unchanged) \param value the value to write to the register field \param mboard the + * motherboard index 0 to M-1 */ - virtual void write_register(const std::string &path, const uint32_t field, const uint64_t value, const size_t mboard = 0) = 0; + virtual void write_register(const std::string& path, + const uint32_t field, + const uint64_t value, + const size_t mboard = 0) = 0; /*! * Read a low-level register field from a register in the USRP hardware @@ -1632,7 +1636,8 @@ public: * \param mboard the motherboard index 0 to M-1 * \return the value of the register field */ - virtual uint64_t read_register(const std::string &path, const uint32_t field, const size_t mboard = 0) = 0; + virtual uint64_t read_register( + const std::string& path, const uint32_t field, const size_t mboard = 0) = 0; /******************************************************************* * Filter API methods @@ -1644,18 +1649,19 @@ public: * \parblock * Select only certain filter names by specifying this search mask. * - * E.g. if search mask is set to "rx_frontends/A" only filter names including that string will be returned. - * \endparblock - * \return a vector of strings representing the selected filter names. + * E.g. if search mask is set to "rx_frontends/A" only filter names including that + * string will be returned. \endparblock \return a vector of strings representing the + * selected filter names. */ - virtual std::vector<std::string> get_filter_names(const std::string &search_mask = "") = 0; + virtual std::vector<std::string> get_filter_names( + const std::string& search_mask = "") = 0; /*! * Return the filter object for the given name. * \param path the name of the filter as returned from get_filter_names(). * \return a filter_info_base::sptr. */ - virtual filter_info_base::sptr get_filter(const std::string &path) = 0; + virtual filter_info_base::sptr get_filter(const std::string& path) = 0; /*! * Write back a filter obtained by get_filter() to the signal path. @@ -1664,10 +1670,10 @@ public: * \param path the name of the filter as returned from get_filter_names(). * \param filter the filter_info_base::sptr of the filter object to be written */ - virtual void set_filter(const std::string &path, filter_info_base::sptr filter) = 0; - + virtual void set_filter(const std::string& path, filter_info_base::sptr filter) = 0; }; -}} +} // namespace usrp +} // namespace uhd #endif /* INCLUDED_UHD_USRP_MULTI_USRP_HPP */ diff --git a/host/include/uhd/usrp/subdev_spec.hpp b/host/include/uhd/usrp/subdev_spec.hpp index 37746a7be..eb526e536 100644 --- a/host/include/uhd/usrp/subdev_spec.hpp +++ b/host/include/uhd/usrp/subdev_spec.hpp @@ -10,78 +10,76 @@ #include <uhd/config.hpp> #include <boost/operators.hpp> -#include <vector> #include <string> +#include <vector> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { - /*! - * A subdevice specification (daughterboard slot, subdevice) name pairing. - */ - struct UHD_API subdev_spec_pair_t : boost::equality_comparable<subdev_spec_pair_t>{ - //! The daughterboard slot name - std::string db_name; +/*! + * A subdevice specification (daughterboard slot, subdevice) name pairing. + */ +struct UHD_API subdev_spec_pair_t : boost::equality_comparable<subdev_spec_pair_t> +{ + //! The daughterboard slot name + std::string db_name; - //! The subdevice name - std::string sd_name; + //! The subdevice name + std::string sd_name; - /*! - * Create a new subdevice specification pair from dboard and subdev names. - * \param db_name the name of a daughterboard slot - * \param sd_name the name of a subdevice on that daughterboard - */ - subdev_spec_pair_t( - const std::string &db_name = "", - const std::string &sd_name = "" - ); + /*! + * Create a new subdevice specification pair from dboard and subdev names. + * \param db_name the name of a daughterboard slot + * \param sd_name the name of a subdevice on that daughterboard + */ + subdev_spec_pair_t(const std::string& db_name = "", const std::string& sd_name = ""); - //! overloaded equality operator - bool operator==(const subdev_spec_pair_t &other); + //! overloaded equality operator + bool operator==(const subdev_spec_pair_t& other); - //! overloaded inquality operator - bool operator!=(const subdev_spec_pair_t &other); - }; + //! overloaded inquality operator + bool operator!=(const subdev_spec_pair_t& other); +}; - //! overloaded comparison operator for subdev_spec_pair_t - UHD_API bool operator==(const subdev_spec_pair_t &, const subdev_spec_pair_t &); +//! overloaded comparison operator for subdev_spec_pair_t +UHD_API bool operator==(const subdev_spec_pair_t&, const subdev_spec_pair_t&); +/*! + * A list of (daughterboard slot name, subdevice name) pairs: + * + * A subdevice specification represents a list of subdevices on a motherboard. + * The subdevices specified may span across multiple daughterboards; + * Hence the need for a subdevice specification over a simple list of strings. + * Typically, the user will pass a RX or TX subdevice specification into the API, + * and the implementation will infer the channel configuration from the specification. + * + * The subdevice specification can be represented as a markup-string. + * The markup-string is a whitespace separated list of dboard:subdev pairs. + * The first pair represents the subdevice for channel zero, + * the second pair represents the subdevice for channel one, and so on. + */ +class UHD_API subdev_spec_t : public std::vector<subdev_spec_pair_t> +{ +public: /*! - * A list of (daughterboard slot name, subdevice name) pairs: - * - * A subdevice specification represents a list of subdevices on a motherboard. - * The subdevices specified may span across multiple daughterboards; - * Hence the need for a subdevice specification over a simple list of strings. - * Typically, the user will pass a RX or TX subdevice specification into the API, - * and the implementation will infer the channel configuration from the specification. - * - * The subdevice specification can be represented as a markup-string. - * The markup-string is a whitespace separated list of dboard:subdev pairs. - * The first pair represents the subdevice for channel zero, - * the second pair represents the subdevice for channel one, and so on. + * Create a subdev specification from a markup string. + * \param markup the markup string */ - class UHD_API subdev_spec_t : public std::vector<subdev_spec_pair_t>{ - public: + subdev_spec_t(const std::string& markup = ""); - /*! - * Create a subdev specification from a markup string. - * \param markup the markup string - */ - subdev_spec_t(const std::string &markup = ""); - - /*! - * Convert a subdev specification into a pretty print string. - * \return a printable string representing the subdev specification - */ - std::string to_pp_string(void) const; + /*! + * Convert a subdev specification into a pretty print string. + * \return a printable string representing the subdev specification + */ + std::string to_pp_string(void) const; - /*! - * Convert the subdevice specification into a markup string. - * The markup string contains the delimiter symbols. - * \return a string with delimiter markup - */ - std::string to_string(void) const; - }; + /*! + * Convert the subdevice specification into a markup string. + * The markup string contains the delimiter symbols. + * \return a string with delimiter markup + */ + std::string to_string(void) const; +}; -}} +}} // namespace uhd::usrp #endif /* INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP */ diff --git a/host/include/uhd/usrp_clock/multi_usrp_clock.hpp b/host/include/uhd/usrp_clock/multi_usrp_clock.hpp index a8fe67684..05759c383 100644 --- a/host/include/uhd/usrp_clock/multi_usrp_clock.hpp +++ b/host/include/uhd/usrp_clock/multi_usrp_clock.hpp @@ -8,15 +8,14 @@ #ifndef INCLUDED_UHD_MULTI_USRP_CLOCK_HPP #define INCLUDED_UHD_MULTI_USRP_CLOCK_HPP -#include <string> -#include <vector> - #include <uhd/config.hpp> #include <uhd/device.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/sensors.hpp> +#include <string> +#include <vector> -namespace uhd{ namespace usrp_clock{ +namespace uhd { namespace usrp_clock { /*! * The Multi-USRP-Clock device class: @@ -43,7 +42,8 @@ namespace uhd{ namespace usrp_clock{ * multi_usrp_clock::sptr clock = multi_usrp_clock::make(dev); * </pre> */ -class UHD_API multi_usrp_clock : boost::noncopyable { +class UHD_API multi_usrp_clock : boost::noncopyable +{ public: typedef boost::shared_ptr<multi_usrp_clock> sptr; @@ -54,7 +54,7 @@ public: * \param dev_addr the device address * \return a new Multi-USRP-Clock object */ - static sptr make(const device_addr_t &dev_addr); + static sptr make(const device_addr_t& dev_addr); /*! * Return the underlying device. @@ -81,7 +81,7 @@ public: * \param board the board index (0 to M-1) * \return a sensor value object */ - virtual sensor_value_t get_sensor(const std::string &name, size_t board = 0) = 0; + virtual sensor_value_t get_sensor(const std::string& name, size_t board = 0) = 0; /*! * Get a list of possible USRP Clock sensor names. @@ -91,7 +91,6 @@ public: virtual std::vector<std::string> get_sensor_names(size_t board = 0) = 0; }; -} //namespace -} //namespace +}} // namespace uhd::usrp_clock #endif /* INCLUDED_UHD_MULTI_USRP_CLOCK_HPP */ diff --git a/host/include/uhd/usrp_clock/octoclock_eeprom.hpp b/host/include/uhd/usrp_clock/octoclock_eeprom.hpp index 3aaa0ad7c..3d514ebc2 100644 --- a/host/include/uhd/usrp_clock/octoclock_eeprom.hpp +++ b/host/include/uhd/usrp_clock/octoclock_eeprom.hpp @@ -13,7 +13,7 @@ #include <uhd/types/dict.hpp> #include <string> -namespace uhd{ namespace usrp_clock{ +namespace uhd { namespace usrp_clock { /*! * The OctoClock EEPROM object: @@ -22,7 +22,8 @@ namespace uhd{ namespace usrp_clock{ * Use the dictionary interface to get and set values. * Commit to the EEPROM to save changed settings. */ -class UHD_API octoclock_eeprom_t : public uhd::dict<std::string, std::string>{ +class UHD_API octoclock_eeprom_t : public uhd::dict<std::string, std::string> +{ public: //! Make a new empty OctoClock EEPROM handler octoclock_eeprom_t(void); @@ -44,10 +45,8 @@ private: uint32_t _proto_ver; void _load(); void _store() const; - }; -} //namespace -} //namespace +}} // namespace uhd::usrp_clock #endif /* INCLUDED_UHD_USRP_CLOCK_OCTOCLOCK_EEPROM_HPP */ diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp index 6c2067918..6a6c611d6 100644 --- a/host/include/uhd/utils/algorithm.hpp +++ b/host/include/uhd/utils/algorithm.hpp @@ -8,74 +8,84 @@ #ifndef INCLUDED_UHD_UTILS_ALGORITHM_HPP #define INCLUDED_UHD_UTILS_ALGORITHM_HPP -#include <algorithm> #include <stdint.h> #include <boost/range/begin.hpp> #include <boost/range/end.hpp> +#include <algorithm> /*! * Useful templated functions, classes, and constants. Some of these overlap * with the STL, but these are created with Boost for portability. * Many of the range wrapper functions come with versions of boost >= 1.43. */ -namespace uhd{ - /*! - * A wrapper around std::sort that takes a range instead of an iterator. - * - * The elements are sorted into ascending order using the less-than operator. - * This wrapper sorts the elements non-destructively into a new range. - * Based on the builtin python function sorted(...) - * - * \param range the range of elements to be sorted - * \return a new range with the elements sorted - */ - template<typename Range> UHD_INLINE Range sorted(const Range &range){ - Range r(range); std::sort(boost::begin(r), boost::end(r)); return r; - } +namespace uhd { +/*! + * A wrapper around std::sort that takes a range instead of an iterator. + * + * The elements are sorted into ascending order using the less-than operator. + * This wrapper sorts the elements non-destructively into a new range. + * Based on the builtin python function sorted(...) + * + * \param range the range of elements to be sorted + * \return a new range with the elements sorted + */ +template <typename Range> UHD_INLINE Range sorted(const Range& range) +{ + Range r(range); + std::sort(boost::begin(r), boost::end(r)); + return r; +} - /*! - * A wrapper around std::reverse that takes a range instead of an iterator. - * - * The elements are reversed into descending order using the less-than operator. - * This wrapper reverses the elements non-destructively into a new range. - * Based on the builtin python function reversed(...) - * - * \param range the range of elements to be reversed - * \return a new range with the elements reversed - */ - template<typename Range> UHD_INLINE Range reversed(const Range &range){ - Range r(range); std::reverse(boost::begin(r), boost::end(r)); return r; - } +/*! + * A wrapper around std::reverse that takes a range instead of an iterator. + * + * The elements are reversed into descending order using the less-than operator. + * This wrapper reverses the elements non-destructively into a new range. + * Based on the builtin python function reversed(...) + * + * \param range the range of elements to be reversed + * \return a new range with the elements reversed + */ +template <typename Range> UHD_INLINE Range reversed(const Range& range) +{ + Range r(range); + std::reverse(boost::begin(r), boost::end(r)); + return r; +} - /*! - * Is the value found within the elements in this range? - * - * Uses std::find to search the iterable for an element. - * - * \param range the elements to search through - * \param value the match to look for in the range - * \return true when the value is found in the range - */ - template<typename Range, typename T> UHD_INLINE - bool has(const Range &range, const T &value){ - return boost::end(range) != std::find(boost::begin(range), boost::end(range), value); - } +/*! + * Is the value found within the elements in this range? + * + * Uses std::find to search the iterable for an element. + * + * \param range the elements to search through + * \param value the match to look for in the range + * \return true when the value is found in the range + */ +template <typename Range, typename T> +UHD_INLINE bool has(const Range& range, const T& value) +{ + return boost::end(range) != std::find(boost::begin(range), boost::end(range), value); +} - /*! - * A templated clip implementation. - * \param val the value to clip between an upper and lower limit - * \param bound1 the upper or lower bound - * \param bound2 the upper or lower bound - * \return the value clipped at the bounds - */ - template<typename T> UHD_INLINE T clip(const T &val, const T &bound1, const T &bound2){ - const T minimum = std::min(bound1, bound2); - if (val < minimum) return minimum; - const T maximum = std::max(bound1, bound2); - if (val > maximum) return maximum; - return val; - } +/*! + * A templated clip implementation. + * \param val the value to clip between an upper and lower limit + * \param bound1 the upper or lower bound + * \param bound2 the upper or lower bound + * \return the value clipped at the bounds + */ +template <typename T> UHD_INLINE T clip(const T& val, const T& bound1, const T& bound2) +{ + const T minimum = std::min(bound1, bound2); + if (val < minimum) + return minimum; + const T maximum = std::max(bound1, bound2); + if (val > maximum) + return maximum; + return val; +} -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_ALGORITHM_HPP */ diff --git a/host/include/uhd/utils/assert_has.hpp b/host/include/uhd/utils/assert_has.hpp index 25f3a2620..281c61ddf 100644 --- a/host/include/uhd/utils/assert_has.hpp +++ b/host/include/uhd/utils/assert_has.hpp @@ -11,26 +11,23 @@ #include <uhd/config.hpp> #include <string> -namespace uhd{ +namespace uhd { - /*! - * Check that an element is found in a container. - * If not, throw a meaningful assertion error. - * The "what" in the error will show what is - * being set and a list of known good values. - * - * \param range a list of possible settings - * \param value an element that may be in the list - * \param what a description of what the value is - * \throw assertion_error when elem not in list - */ - template<typename T, typename Range> void assert_has( - const Range &range, - const T &value, - const std::string &what = "unknown" - ); +/*! + * Check that an element is found in a container. + * If not, throw a meaningful assertion error. + * The "what" in the error will show what is + * being set and a list of known good values. + * + * \param range a list of possible settings + * \param value an element that may be in the list + * \param what a description of what the value is + * \throw assertion_error when elem not in list + */ +template <typename T, typename Range> +void assert_has(const Range& range, const T& value, const std::string& what = "unknown"); -}//namespace uhd +} // namespace uhd #include <uhd/utils/assert_has.ipp> diff --git a/host/include/uhd/utils/byteswap.hpp b/host/include/uhd/utils/byteswap.hpp index a8fa81e19..e05a6cced 100644 --- a/host/include/uhd/utils/byteswap.hpp +++ b/host/include/uhd/utils/byteswap.hpp @@ -16,36 +16,36 @@ * Provide fast byteswaping routines for 16, 32, and 64 bit integers, * by using the system's native routines/intrinsics when available. */ -namespace uhd{ +namespace uhd { - //! perform a byteswap on a 16 bit integer - uint16_t byteswap(uint16_t); +//! perform a byteswap on a 16 bit integer +uint16_t byteswap(uint16_t); - //! perform a byteswap on a 32 bit integer - uint32_t byteswap(uint32_t); +//! perform a byteswap on a 32 bit integer +uint32_t byteswap(uint32_t); - //! perform a byteswap on a 64 bit integer - uint64_t byteswap(uint64_t); +//! perform a byteswap on a 64 bit integer +uint64_t byteswap(uint64_t); - //! network to host: short, long, or long-long - template<typename T> T ntohx(T); +//! network to host: short, long, or long-long +template <typename T> T ntohx(T); - //! host to network: short, long, or long-long - template<typename T> T htonx(T); +//! host to network: short, long, or long-long +template <typename T> T htonx(T); - //! worknet to host: short, long, or long-long - // - // The argument is assumed to be little-endian (i.e, the inverse - // of typical network endianness). - template<typename T> T wtohx(T); +//! worknet to host: short, long, or long-long +// +// The argument is assumed to be little-endian (i.e, the inverse +// of typical network endianness). +template <typename T> T wtohx(T); - //! host to worknet: short, long, or long-long - // - // The return value is little-endian (i.e, the inverse - // of typical network endianness). - template<typename T> T htowx(T); +//! host to worknet: short, long, or long-long +// +// The return value is little-endian (i.e, the inverse +// of typical network endianness). +template <typename T> T htowx(T); -} //namespace uhd +} // namespace uhd #include <uhd/utils/byteswap.ipp> diff --git a/host/include/uhd/utils/cast.hpp b/host/include/uhd/utils/cast.hpp index 0944c012a..d6d86d119 100644 --- a/host/include/uhd/utils/cast.hpp +++ b/host/include/uhd/utils/cast.hpp @@ -9,25 +9,24 @@ #define INCLUDED_UHD_UTILS_CAST_HPP #include <uhd/config.hpp> -#include <string> #include <sstream> +#include <string> -namespace uhd{ namespace cast{ - //! Convert a hexadecimal string into a value. - // - // Example: - // uint16_t x = hexstr_cast<uint16_t>("0xDEADBEEF"); - // Uses stringstream. - template<typename T> UHD_INLINE T hexstr_cast(const std::string &in) - { - T x; - std::stringstream ss; - ss << std::hex << in; - ss >> x; - return x; - } +namespace uhd { namespace cast { +//! Convert a hexadecimal string into a value. +// +// Example: +// uint16_t x = hexstr_cast<uint16_t>("0xDEADBEEF"); +// Uses stringstream. +template <typename T> UHD_INLINE T hexstr_cast(const std::string& in) +{ + T x; + std::stringstream ss; + ss << std::hex << in; + ss >> x; + return x; +} -}} //namespace uhd::cast +}} // namespace uhd::cast #endif /* INCLUDED_UHD_UTILS_CAST_HPP */ - diff --git a/host/include/uhd/utils/csv.hpp b/host/include/uhd/utils/csv.hpp index dbc73695b..90933d416 100644 --- a/host/include/uhd/utils/csv.hpp +++ b/host/include/uhd/utils/csv.hpp @@ -9,17 +9,17 @@ #define INCLUDED_UHD_UTILS_CSV_HPP #include <uhd/config.hpp> -#include <vector> -#include <string> #include <istream> +#include <string> +#include <vector> -namespace uhd{ namespace csv{ - typedef std::vector<std::string> row_type; - typedef std::vector<row_type> rows_type; +namespace uhd { namespace csv { +typedef std::vector<std::string> row_type; +typedef std::vector<row_type> rows_type; - //! Convert an input stream to csv rows. - UHD_API rows_type to_rows(std::istream &input); +//! Convert an input stream to csv rows. +UHD_API rows_type to_rows(std::istream& input); -}} //namespace uhd::csv +}} // namespace uhd::csv #endif /* INCLUDED_UHD_UTILS_CSV_HPP */ diff --git a/host/include/uhd/utils/dirty_tracked.hpp b/host/include/uhd/utils/dirty_tracked.hpp index 1fbfddc6f..8fb390a8b 100644 --- a/host/include/uhd/utils/dirty_tracked.hpp +++ b/host/include/uhd/utils/dirty_tracked.hpp @@ -8,115 +8,126 @@ #ifndef INCLUDED_UHD_UTILS_DIRTY_TRACKED_HPP #define INCLUDED_UHD_UTILS_DIRTY_TRACKED_HPP -namespace uhd{ +namespace uhd { +/*! + * A class that wraps a data value with a dirty flag + * When the client uses the assignment operator on this object, the object + * automatically dirties itself if the assigned type is not equal the underlying + * data. Data can be cleaned using the mark_clean entry-point. + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ +template <typename data_t> class dirty_tracked +{ +public: /*! - * A class that wraps a data value with a dirty flag - * When the client uses the assignment operator on this object, the object - * automatically dirties itself if the assigned type is not equal the underlying - * data. Data can be cleaned using the mark_clean entry-point. - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) + * Default ctor: Initialize to default value and dirty */ - template<typename data_t> - class dirty_tracked { - public: - /*! - * Default ctor: Initialize to default value and dirty - */ - dirty_tracked() : - _data(), //data_t must have a default ctor - _dirty(true) - {} + dirty_tracked() + : _data() + , // data_t must have a default ctor + _dirty(true) + { + } - /*! - * Initialize to specified value and dirty - */ - dirty_tracked(const data_t& value) : - _data(value), //data_t must have a copy ctor - _dirty(true) - {} + /*! + * Initialize to specified value and dirty + */ + dirty_tracked(const data_t& value) + : _data(value) + , // data_t must have a copy ctor + _dirty(true) + { + } - /*! - * Copy ctor: Assign source to this type - */ - dirty_tracked(const dirty_tracked& source) { - *this = source; - } + /*! + * Copy ctor: Assign source to this type + */ + dirty_tracked(const dirty_tracked& source) + { + *this = source; + } - /*! - * Get underlying data - */ - UHD_INLINE const data_t& get() const { - return _data; - } + /*! + * Get underlying data + */ + UHD_INLINE const data_t& get() const + { + return _data; + } - /*! - * Has the underlying data changed since the last - * time it was cleaned? - */ - UHD_INLINE bool is_dirty() const { - return _dirty; - } + /*! + * Has the underlying data changed since the last + * time it was cleaned? + */ + UHD_INLINE bool is_dirty() const + { + return _dirty; + } - /*! - * Mark the underlying data as clean - */ - UHD_INLINE void mark_clean() { - _dirty = false; - } + /*! + * Mark the underlying data as clean + */ + UHD_INLINE void mark_clean() + { + _dirty = false; + } - /*! - * Mark the underlying data as dirty - */ - UHD_INLINE void force_dirty() { - _dirty = true; - } + /*! + * Mark the underlying data as dirty + */ + UHD_INLINE void force_dirty() + { + _dirty = true; + } - /*! - * Assignment with data. - * Store the specified value and mark it as dirty - * if it is not equal to the underlying data. - */ - UHD_INLINE dirty_tracked& operator=(const data_t& value) - { - if(!(_data == value)) { //data_t must have an equality operator - _dirty = true; - _data = value; //data_t must have an assignment operator - } - return *this; + /*! + * Assignment with data. + * Store the specified value and mark it as dirty + * if it is not equal to the underlying data. + */ + UHD_INLINE dirty_tracked& operator=(const data_t& value) + { + if (!(_data == value)) { // data_t must have an equality operator + _dirty = true; + _data = value; // data_t must have an assignment operator } + return *this; + } - /*! - * Assignment with dirty tracked type. - * Store the specified value from dirty type and mark it as dirty - * if it is not equal to the underlying data. - * This exists to optimize out an implicit cast from dirty_tracked - * type to data type. - */ - UHD_INLINE dirty_tracked& operator=(const dirty_tracked& source) { - if (!(_data == source._data)) { - _dirty = true; - _data = source._data; - } - return *this; + /*! + * Assignment with dirty tracked type. + * Store the specified value from dirty type and mark it as dirty + * if it is not equal to the underlying data. + * This exists to optimize out an implicit cast from dirty_tracked + * type to data type. + */ + UHD_INLINE dirty_tracked& operator=(const dirty_tracked& source) + { + if (!(_data == source._data)) { + _dirty = true; + _data = source._data; } + return *this; + } - /*! - * Explicit conversion from this type to data_t - */ - UHD_INLINE operator const data_t&() const { - return get(); - } + /*! + * Explicit conversion from this type to data_t + */ + UHD_INLINE operator const data_t&() const + { + return get(); + } - private: - data_t _data; - bool _dirty; - }; +private: + data_t _data; + bool _dirty; +}; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_DIRTY_TRACKED_HPP */ diff --git a/host/include/uhd/utils/gain_group.hpp b/host/include/uhd/utils/gain_group.hpp index 128577c39..9822f3620 100644 --- a/host/include/uhd/utils/gain_group.hpp +++ b/host/include/uhd/utils/gain_group.hpp @@ -10,24 +10,26 @@ #include <uhd/config.hpp> #include <uhd/types/ranges.hpp> -#include <boost/shared_ptr.hpp> #include <boost/function.hpp> +#include <boost/shared_ptr.hpp> #include <boost/utility.hpp> -#include <vector> #include <string> +#include <vector> -namespace uhd{ +namespace uhd { /*! * A set of function to control a gain element. */ -struct UHD_API gain_fcns_t{ +struct UHD_API gain_fcns_t +{ boost::function<gain_range_t(void)> get_range; - boost::function<double(void)> get_value; - boost::function<void(double)> set_value; + boost::function<double(void)> get_value; + boost::function<void(double)> set_value; }; -class UHD_API gain_group : boost::noncopyable{ +class UHD_API gain_group : boost::noncopyable +{ public: typedef boost::shared_ptr<gain_group> sptr; @@ -40,7 +42,7 @@ public: * \param name name of the gain element (optional) * \return a gain range with overall min, max, step */ - virtual gain_range_t get_range(const std::string &name = "") = 0; + virtual gain_range_t get_range(const std::string& name = "") = 0; /*! * Get the gain value for the gain element specified by name. @@ -48,7 +50,7 @@ public: * \param name name of the gain element (optional) * \return a gain value of the element or all elements */ - virtual double get_value(const std::string &name = "") = 0; + virtual double get_value(const std::string& name = "") = 0; /*! * Set the gain value for the gain element specified by name. @@ -58,7 +60,7 @@ public: * \param gain the gain to set for the element or across the group * \param name name of the gain element (optional) */ - virtual void set_value(double gain, const std::string &name = "") = 0; + virtual void set_value(double gain, const std::string& name = "") = 0; /*! * Get a list of names of registered gain elements. @@ -82,10 +84,7 @@ public: * \param priority the priority of the gain element */ virtual void register_fcns( - const std::string &name, - const gain_fcns_t &gain_fcns, - size_t priority = 0 - ) = 0; + const std::string& name, const gain_fcns_t& gain_fcns, size_t priority = 0) = 0; /*! * Make a new empty gain group. @@ -94,7 +93,6 @@ public: static sptr make(void); }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_GAIN_GROUP_HPP */ - diff --git a/host/include/uhd/utils/log.hpp b/host/include/uhd/utils/log.hpp index 584ba2cad..95ba8e670 100644 --- a/host/include/uhd/utils/log.hpp +++ b/host/include/uhd/utils/log.hpp @@ -11,10 +11,10 @@ #include <uhd/config.hpp> #include <boost/current_function.hpp> #include <boost/thread/thread.hpp> +#include <iostream> #include <ostream> -#include <string> #include <sstream> -#include <iostream> +#include <string> /*! \file log.hpp * @@ -94,85 +94,83 @@ * fatal: 5 */ -namespace uhd { - namespace log { - /*! Logging severity levels - * - * Either numeric value or string can be used to define loglevel in - * CMake and environment variables - */ - enum severity_level { - trace = 0, /**< displays every available log message */ - debug = 1, /**< displays most log messages necessary for debugging internals */ - info = 2, /**< informational messages about setup and what is going on*/ - warning = 3, /**< something is not right but operation can continue */ - error = 4, /**< something has gone wrong */ - fatal = 5, /**< something has gone horribly wrong */ - off = 6, /**< logging is turned off */ - }; - - /*! Logging info structure - * - * Information needed to create a log entry is fully contained in the - * logging_info structure. - */ - struct UHD_API logging_info { - logging_info() - : verbosity(uhd::log::off) {} - logging_info( - const boost::posix_time::ptime &time_, - const uhd::log::severity_level &verbosity_, - const std::string &file_, - const unsigned int &line_, - const std::string &component_, - const boost::thread::id &thread_id_ - ) : time(time_), - verbosity(verbosity_), - file(file_), - line(line_), - component(component_), - thread_id(thread_id_) - { /* nop */ } - - boost::posix_time::ptime time; - uhd::log::severity_level verbosity; - std::string file; - unsigned int line; - std::string component; - boost::thread::id thread_id; - std::string message; - }; - - /*! Set the global log level - * - * The global log level gets applied before the specific log level. - * So, if the global log level is 'info', no logger can can print - * messages at level 'debug' or below. - */ - UHD_API void set_log_level(uhd::log::severity_level level); - - /*! Set the log level for the console logger (if defined). - * - * Short-hand for `set_logger_level("console", level);` - */ - UHD_API void set_console_level(uhd::log::severity_level level); - - /*! Set the log level for the file logger (if defined) - * - * Short-hand for `set_logger_level("file", level);` - */ - UHD_API void set_file_level(uhd::log::severity_level level); - - /*! Set the log level for any specific logger. - * - * \param logger Name of the logger - * \param level New log level for this logger. - * - * \throws uhd::key_error if \p logger was not defined - */ - UHD_API void set_logger_level(const std::string &logger, uhd::log::severity_level level); +namespace uhd { namespace log { +/*! Logging severity levels + * + * Either numeric value or string can be used to define loglevel in + * CMake and environment variables + */ +enum severity_level { + trace = 0, /**< displays every available log message */ + debug = 1, /**< displays most log messages necessary for debugging internals */ + info = 2, /**< informational messages about setup and what is going on*/ + warning = 3, /**< something is not right but operation can continue */ + error = 4, /**< something has gone wrong */ + fatal = 5, /**< something has gone horribly wrong */ + off = 6, /**< logging is turned off */ +}; + +/*! Logging info structure + * + * Information needed to create a log entry is fully contained in the + * logging_info structure. + */ +struct UHD_API logging_info +{ + logging_info() : verbosity(uhd::log::off) {} + logging_info(const boost::posix_time::ptime& time_, + const uhd::log::severity_level& verbosity_, + const std::string& file_, + const unsigned int& line_, + const std::string& component_, + const boost::thread::id& thread_id_) + : time(time_) + , verbosity(verbosity_) + , file(file_) + , line(line_) + , component(component_) + , thread_id(thread_id_) + { /* nop */ } -} + + boost::posix_time::ptime time; + uhd::log::severity_level verbosity; + std::string file; + unsigned int line; + std::string component; + boost::thread::id thread_id; + std::string message; +}; + +/*! Set the global log level + * + * The global log level gets applied before the specific log level. + * So, if the global log level is 'info', no logger can can print + * messages at level 'debug' or below. + */ +UHD_API void set_log_level(uhd::log::severity_level level); + +/*! Set the log level for the console logger (if defined). + * + * Short-hand for `set_logger_level("console", level);` + */ +UHD_API void set_console_level(uhd::log::severity_level level); + +/*! Set the log level for the file logger (if defined) + * + * Short-hand for `set_logger_level("file", level);` + */ +UHD_API void set_file_level(uhd::log::severity_level level); + +/*! Set the log level for any specific logger. + * + * \param logger Name of the logger + * \param level New log level for this logger. + * + * \throws uhd::key_error if \p logger was not defined + */ +UHD_API void set_logger_level(const std::string& logger, uhd::log::severity_level level); +}} // namespace uhd::log //! \cond //! Internal logging macro to be used in other macros @@ -182,45 +180,45 @@ namespace uhd { // macro-style logging (compile-time determined) #if UHD_LOG_MIN_LEVEL < 1 -#define UHD_LOG_TRACE(component, message) \ - _UHD_LOG_INTERNAL(component, uhd::log::trace) << message; +# define UHD_LOG_TRACE(component, message) \ + _UHD_LOG_INTERNAL(component, uhd::log::trace) << message; #else -#define UHD_LOG_TRACE(component, message) +# define UHD_LOG_TRACE(component, message) #endif #if UHD_LOG_MIN_LEVEL < 2 -#define UHD_LOG_DEBUG(component, message) \ - _UHD_LOG_INTERNAL(component, uhd::log::debug) << message; +# define UHD_LOG_DEBUG(component, message) \ + _UHD_LOG_INTERNAL(component, uhd::log::debug) << message; #else -#define UHD_LOG_DEBUG(component, message) +# define UHD_LOG_DEBUG(component, message) #endif #if UHD_LOG_MIN_LEVEL < 3 -#define UHD_LOG_INFO(component, message) \ - _UHD_LOG_INTERNAL(component, uhd::log::info) << message; +# define UHD_LOG_INFO(component, message) \ + _UHD_LOG_INTERNAL(component, uhd::log::info) << message; #else -#define UHD_LOG_INFO(component, message) +# define UHD_LOG_INFO(component, message) #endif #if UHD_LOG_MIN_LEVEL < 4 -#define UHD_LOG_WARNING(component, message) \ - _UHD_LOG_INTERNAL(component, uhd::log::warning) << message; +# define UHD_LOG_WARNING(component, message) \ + _UHD_LOG_INTERNAL(component, uhd::log::warning) << message; #else -#define UHD_LOG_WARNING(component, message) +# define UHD_LOG_WARNING(component, message) #endif #if UHD_LOG_MIN_LEVEL < 5 -#define UHD_LOG_ERROR(component, message) \ - _UHD_LOG_INTERNAL(component, uhd::log::error) << message; +# define UHD_LOG_ERROR(component, message) \ + _UHD_LOG_INTERNAL(component, uhd::log::error) << message; #else -#define UHD_LOG_ERROR(component, message) +# define UHD_LOG_ERROR(component, message) #endif #if UHD_LOG_MIN_LEVEL < 6 -#define UHD_LOG_FATAL(component, message) \ - _UHD_LOG_INTERNAL(component, uhd::log::fatal) << message; +# define UHD_LOG_FATAL(component, message) \ + _UHD_LOG_INTERNAL(component, uhd::log::fatal) << message; #else -#define UHD_LOG_FATAL(component, message) +# define UHD_LOG_FATAL(component, message) #endif #ifndef UHD_LOG_FASTPATH_DISABLE @@ -228,10 +226,9 @@ namespace uhd { // No metadata is tracked. Only the message is displayed. This does not go // through the regular backends. Mostly used for printing the UOSDL characters // during streaming. -#define UHD_LOG_FASTPATH(message) \ - uhd::_log::log_fastpath(message); +# define UHD_LOG_FASTPATH(message) uhd::_log::log_fastpath(message); #else -#define UHD_LOG_FASTPATH(message) +# define UHD_LOG_FASTPATH(message) #endif // iostream-style logging @@ -245,67 +242,67 @@ namespace uhd { #if defined(__GNUG__) //! Helpful debug tool to print site info -#define UHD_HERE() \ - UHD_LOGGER_DEBUG("DEBUG") << __FILE__ << ":" << __LINE__ << " (" << __PRETTY_FUNCTION__ << ")"; +# define UHD_HERE() \ + UHD_LOGGER_DEBUG("DEBUG") \ + << __FILE__ << ":" << __LINE__ << " (" << __PRETTY_FUNCTION__ << ")"; #else //! Helpful debug tool to print site info -#define UHD_HERE() \ - UHD_LOGGER_DEBUG("DEBUG") << __FILE__ << ":" << __LINE__; +# define UHD_HERE() UHD_LOGGER_DEBUG("DEBUG") << __FILE__ << ":" << __LINE__; #endif //! Helpful debug tool to print a variable -#define UHD_VAR(var) \ - UHD_LOGGER_DEBUG("DEBUG") << #var << " = " << var; +#define UHD_VAR(var) UHD_LOGGER_DEBUG("DEBUG") << #var << " = " << var; //! Helpful debug tool to print a variable in hex -#define UHD_HEX(var) \ - UHD_LOGGER_DEBUG("DEBUG") << #var << " = 0x" << std::hex << std::setfill('0') << std::setw(8) << var << std::dec; +#define UHD_HEX(var) \ + UHD_LOGGER_DEBUG("DEBUG") << #var << " = 0x" << std::hex << std::setfill('0') \ + << std::setw(8) << var << std::dec; //! \cond -namespace uhd{ namespace _log { - - //! Fastpath logging - void UHD_API log_fastpath(const std::string &); - - //! Internal logging object (called by UHD_LOG* macros) - class UHD_API log { - public: - log( - const uhd::log::severity_level verbosity, - const std::string &file, - const unsigned int line, - const std::string &component, - const boost::thread::id thread_id - ); - - ~log(void); - - // Macro for overloading insertion operators to avoid costly - // conversion of types if not logging. - #define INSERTION_OVERLOAD(x) log& operator<< (x) \ - { \ - if(_log_it) { \ - _ss << val ; \ - } \ - return *this; \ - } - - // General insertion overload - template <typename T> - INSERTION_OVERLOAD(T val) - - // Insertion overloads for std::ostream manipulators - INSERTION_OVERLOAD(std::ostream& (*val)(std::ostream&)) +namespace uhd { +namespace _log { + +//! Fastpath logging +void UHD_API log_fastpath(const std::string&); + +//! Internal logging object (called by UHD_LOG* macros) +class UHD_API log +{ +public: + log(const uhd::log::severity_level verbosity, + const std::string& file, + const unsigned int line, + const std::string& component, + const boost::thread::id thread_id); + + ~log(void); + +// Macro for overloading insertion operators to avoid costly +// conversion of types if not logging. +#define INSERTION_OVERLOAD(x) \ + log& operator<<(x) \ + { \ + if (_log_it) { \ + _ss << val; \ + } \ + return *this; \ + } + + // General insertion overload + template <typename T> + INSERTION_OVERLOAD(T val) + + // Insertion overloads for std::ostream manipulators + INSERTION_OVERLOAD(std::ostream& (*val)(std::ostream&)) INSERTION_OVERLOAD(std::ios& (*val)(std::ios&)) - INSERTION_OVERLOAD(std::ios_base& (*val)(std::ios_base&)) + INSERTION_OVERLOAD(std::ios_base& (*val)(std::ios_base&)) - private: - uhd::log::logging_info _log_info; - std::ostringstream _ss; - const bool _log_it; - }; + private : uhd::log::logging_info _log_info; + std::ostringstream _ss; + const bool _log_it; +}; -} //namespace uhd::_log +} // namespace _log //! \endcond } /* namespace uhd */ diff --git a/host/include/uhd/utils/log_add.hpp b/host/include/uhd/utils/log_add.hpp index 3b552d3a4..36a34523e 100644 --- a/host/include/uhd/utils/log_add.hpp +++ b/host/include/uhd/utils/log_add.hpp @@ -13,23 +13,21 @@ #include <uhd/utils/log.hpp> #include <functional> -namespace uhd { - namespace log { +namespace uhd { namespace log { - /*! Logging function type - * - * Every logging_backend has to define a function with this signature. - * Can be added to the logging core. - */ - typedef std::function<void(const uhd::log::logging_info&)> log_fn_t ; +/*! Logging function type + * + * Every logging_backend has to define a function with this signature. + * Can be added to the logging core. + */ +typedef std::function<void(const uhd::log::logging_info&)> log_fn_t; - /*! Add logging backend to the log system - * - * \param key Identifies the logging backend in the logging core - * \param logger_fn function which actually logs messages to this backend - */ - UHD_API void add_logger(const std::string &key, log_fn_t logger_fn); - } -} /* namespace uhd::log */ +/*! Add logging backend to the log system + * + * \param key Identifies the logging backend in the logging core + * \param logger_fn function which actually logs messages to this backend + */ +UHD_API void add_logger(const std::string& key, log_fn_t logger_fn); +}} /* namespace uhd::log */ #endif /* INCLUDED_UHD_UTILS_LOG_ADD_HPP */ diff --git a/host/include/uhd/utils/math.hpp b/host/include/uhd/utils/math.hpp index b0e7dd145..e9f8efb57 100644 --- a/host/include/uhd/utils/math.hpp +++ b/host/include/uhd/utils/math.hpp @@ -8,10 +8,10 @@ #ifndef INCLUDED_UHD_UTILS_MATH_HPP #define INCLUDED_UHD_UTILS_MATH_HPP -#include <cmath> #include <uhd/config.hpp> #include <stdint.h> #include <boost/numeric/conversion/bounds.hpp> +#include <cmath> namespace uhd { @@ -21,213 +21,221 @@ namespace uhd { */ namespace math { - /*! - * Define epsilon values for floating point comparisons. - * - * There are a lot of different sources for epsilon values that we could use - * for this. For single-precision (f32), most machines will report an - * epsilon of 1.192e-7, and for double-precision (f64) most machines will - * report an epsilon of 2.220e-16. The issue is that these are not always - * appropriate, depending on the scale of the operands and how they have - * been rounded in previous calculations. The values defined here are - * defaults, but should be overridden for calculations depending on the - * application. - * - * If a particular comparison is operating using very small or very large - * values, a custom epsilon should be defined for those computations. This - * use-case is provided for in the `fp_compare_epsilon` class constructor. - */ - static const float SINGLE_PRECISION_EPSILON = 1.19e-7f; - static const double DOUBLE_PRECISION_EPSILON = 2.22e-16; +/*! + * Define epsilon values for floating point comparisons. + * + * There are a lot of different sources for epsilon values that we could use + * for this. For single-precision (f32), most machines will report an + * epsilon of 1.192e-7, and for double-precision (f64) most machines will + * report an epsilon of 2.220e-16. The issue is that these are not always + * appropriate, depending on the scale of the operands and how they have + * been rounded in previous calculations. The values defined here are + * defaults, but should be overridden for calculations depending on the + * application. + * + * If a particular comparison is operating using very small or very large + * values, a custom epsilon should be defined for those computations. This + * use-case is provided for in the `fp_compare_epsilon` class constructor. + */ +static const float SINGLE_PRECISION_EPSILON = 1.19e-7f; +static const double DOUBLE_PRECISION_EPSILON = 2.22e-16; namespace fp_compare { - /*! - * Class for floating-point comparisons using an epsilon. - * - * At construction, you can specify the epsilon to use for the comparisons. - * This class, combined with the operators under it, allow for - * epsilon-comparisons of floats. An example is: - * - * // Compare floats 'x' and 'y'. - * bool x_equals_y = (fp_compare_epsilon<float>(x) == y); - * - * // Compare doubles 'x' and 'y'. - * bool x_equals_y = (fp_compare_epsilon<double>(x) == y); - */ - template<typename float_t> class fp_compare_epsilon { - public: - UHD_INLINE fp_compare_epsilon(float_t value); - UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon); - UHD_INLINE fp_compare_epsilon(const fp_compare_epsilon<float_t>& copy); - UHD_INLINE ~fp_compare_epsilon(); - UHD_INLINE void operator=(const fp_compare_epsilon& copy); - - float_t _value; - float_t _epsilon; - }; - - /* A Note on Floating Point Equality with Epsilons - * - * There are obviously a lot of strategies for defining floating point - * equality, and in the end it all comes down to the domain at hand. UHD's - * floating-point-with-epsilon comparison algorithm is based on the method - * presented in Knuth's "The Art of Computer Science" called "very close - * with tolerance epsilon". - * - * [(|u - v| / |u|) <= e] && [(|u - v| / |v|) <= e] - * - * UHD's modification to this algorithm is using the denominator's epsilon - * value (since each float_t object has its own epsilon) for each - * comparison. - */ - - template<typename float_t> UHD_INLINE - bool operator==(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator!=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>=(fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); - - /* If these operators are used with floats, we rely on type promotion to - * double. */ - template<typename float_t> UHD_INLINE - bool operator==(fp_compare_epsilon<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator!=(fp_compare_epsilon<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator<(fp_compare_epsilon<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator>(fp_compare_epsilon<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator>=(fp_compare_epsilon<float_t> lhs, double rhs); - - template<typename float_t> UHD_INLINE - bool operator==(double lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator!=(double lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<(double lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>(double lhs, fp_compare_epsilon<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>=(double lhs, fp_compare_epsilon<float_t> rhs); +/*! + * Class for floating-point comparisons using an epsilon. + * + * At construction, you can specify the epsilon to use for the comparisons. + * This class, combined with the operators under it, allow for + * epsilon-comparisons of floats. An example is: + * + * // Compare floats 'x' and 'y'. + * bool x_equals_y = (fp_compare_epsilon<float>(x) == y); + * + * // Compare doubles 'x' and 'y'. + * bool x_equals_y = (fp_compare_epsilon<double>(x) == y); + */ +template <typename float_t> class fp_compare_epsilon +{ +public: + UHD_INLINE fp_compare_epsilon(float_t value); + UHD_INLINE fp_compare_epsilon(float_t value, float_t epsilon); + UHD_INLINE fp_compare_epsilon(const fp_compare_epsilon<float_t>& copy); + UHD_INLINE ~fp_compare_epsilon(); + UHD_INLINE void operator=(const fp_compare_epsilon& copy); + + float_t _value; + float_t _epsilon; +}; + +/* A Note on Floating Point Equality with Epsilons + * + * There are obviously a lot of strategies for defining floating point + * equality, and in the end it all comes down to the domain at hand. UHD's + * floating-point-with-epsilon comparison algorithm is based on the method + * presented in Knuth's "The Art of Computer Science" called "very close + * with tolerance epsilon". + * + * [(|u - v| / |u|) <= e] && [(|u - v| / |v|) <= e] + * + * UHD's modification to this algorithm is using the denominator's epsilon + * value (since each float_t object has its own epsilon) for each + * comparison. + */ + +template <typename float_t> +UHD_INLINE bool operator==( + fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator!=( + fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<( + fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<=( + fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>( + fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>=( + fp_compare_epsilon<float_t> lhs, fp_compare_epsilon<float_t> rhs); + +/* If these operators are used with floats, we rely on type promotion to + * double. */ +template <typename float_t> +UHD_INLINE bool operator==(fp_compare_epsilon<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator!=(fp_compare_epsilon<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator<(fp_compare_epsilon<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator<=(fp_compare_epsilon<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator>(fp_compare_epsilon<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator>=(fp_compare_epsilon<float_t> lhs, double rhs); + +template <typename float_t> +UHD_INLINE bool operator==(double lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator!=(double lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<(double lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<=(double lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>(double lhs, fp_compare_epsilon<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>=(double lhs, fp_compare_epsilon<float_t> rhs); } // namespace fp_compare - /*! - * Define delta values for floating point comparisons. - * - * These are the default deltas used by the 'fp_compare_delta' class for - * single and double-precision floating point comparisons. - */ - static const float SINGLE_PRECISION_DELTA = 1e-3f; - static const double DOUBLE_PRECISION_DELTA = 1e-5; +/*! + * Define delta values for floating point comparisons. + * + * These are the default deltas used by the 'fp_compare_delta' class for + * single and double-precision floating point comparisons. + */ +static const float SINGLE_PRECISION_DELTA = 1e-3f; +static const double DOUBLE_PRECISION_DELTA = 1e-5; - /*! Floating-point delta to use for frequency comparisons. */ - static const double FREQ_COMPARISON_DELTA_HZ = 0.1; +/*! Floating-point delta to use for frequency comparisons. */ +static const double FREQ_COMPARISON_DELTA_HZ = 0.1; namespace fp_compare { /*! - * Class for floating-point comparisons using a delta. - * - * At construction, you can specify the delta to use for the comparisons. - * This class, combined with the operators under it, allow for - * delta-comparisons of floats. An example is: - * - * // Compare floats 'x' and 'y'. - * bool x_equals_y = (fp_compare_delta<float>(x) == y); - * - * // Compare doubles 'x' and 'y'. - * bool x_equals_y = (fp_compare_delta<double>(x) == y); - */ - template<typename float_t> class fp_compare_delta { - public: - UHD_INLINE fp_compare_delta(float_t value); - UHD_INLINE fp_compare_delta(float_t value, float_t delta); - UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy); - UHD_INLINE ~fp_compare_delta(); - UHD_INLINE void operator=(const fp_compare_delta& copy); - - float_t _value; - float_t _delta; - }; - - template<typename float_t> UHD_INLINE - bool operator==(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator!=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); - - /* If these operators are used with floats, we rely on type promotion to - * double. */ - template<typename float_t> UHD_INLINE - bool operator==(fp_compare_delta<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator!=(fp_compare_delta<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator<(fp_compare_delta<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator<=(fp_compare_delta<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator>(fp_compare_delta<float_t> lhs, double rhs); - template<typename float_t> UHD_INLINE - bool operator>=(fp_compare_delta<float_t> lhs, double rhs); - - template<typename float_t> UHD_INLINE - bool operator==(double lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator!=(double lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<(double lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator<=(double lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>(double lhs, fp_compare_delta<float_t> rhs); - template<typename float_t> UHD_INLINE - bool operator>=(double lhs, fp_compare_delta<float_t> rhs); + * Class for floating-point comparisons using a delta. + * + * At construction, you can specify the delta to use for the comparisons. + * This class, combined with the operators under it, allow for + * delta-comparisons of floats. An example is: + * + * // Compare floats 'x' and 'y'. + * bool x_equals_y = (fp_compare_delta<float>(x) == y); + * + * // Compare doubles 'x' and 'y'. + * bool x_equals_y = (fp_compare_delta<double>(x) == y); + */ +template <typename float_t> class fp_compare_delta +{ +public: + UHD_INLINE fp_compare_delta(float_t value); + UHD_INLINE fp_compare_delta(float_t value, float_t delta); + UHD_INLINE fp_compare_delta(const fp_compare_delta<float_t>& copy); + UHD_INLINE ~fp_compare_delta(); + UHD_INLINE void operator=(const fp_compare_delta& copy); + + float_t _value; + float_t _delta; +}; + +template <typename float_t> +UHD_INLINE bool operator==(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator!=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>=(fp_compare_delta<float_t> lhs, fp_compare_delta<float_t> rhs); + +/* If these operators are used with floats, we rely on type promotion to + * double. */ +template <typename float_t> +UHD_INLINE bool operator==(fp_compare_delta<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator!=(fp_compare_delta<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator<(fp_compare_delta<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator<=(fp_compare_delta<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator>(fp_compare_delta<float_t> lhs, double rhs); +template <typename float_t> +UHD_INLINE bool operator>=(fp_compare_delta<float_t> lhs, double rhs); + +template <typename float_t> +UHD_INLINE bool operator==(double lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator!=(double lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<(double lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator<=(double lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>(double lhs, fp_compare_delta<float_t> rhs); +template <typename float_t> +UHD_INLINE bool operator>=(double lhs, fp_compare_delta<float_t> rhs); } // namespace fp_compare - UHD_INLINE bool frequencies_are_equal(double lhs, double rhs) { - return(fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ) - == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ)); - } +UHD_INLINE bool frequencies_are_equal(double lhs, double rhs) +{ + return (fp_compare::fp_compare_delta<double>(lhs, FREQ_COMPARISON_DELTA_HZ) + == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ)); +} - //! Portable log2() - template <typename float_t> UHD_INLINE - float_t log2(float_t x) - { - // C++11 defines std::log2(), when that's universally supported - // we can switch over. - return std::log(x) / std::log(float_t(2)); - } +//! Portable log2() +template <typename float_t> UHD_INLINE float_t log2(float_t x) +{ + // C++11 defines std::log2(), when that's universally supported + // we can switch over. + return std::log(x) / std::log(float_t(2)); +} } // namespace math } // namespace uhd -#include <uhd/utils/fp_compare_epsilon.ipp> #include <uhd/utils/fp_compare_delta.ipp> +#include <uhd/utils/fp_compare_epsilon.ipp> #endif /* INCLUDED_UHD_UTILS_MATH_HPP */ diff --git a/host/include/uhd/utils/msg_task.hpp b/host/include/uhd/utils/msg_task.hpp index 18490c363..f19f8010d 100644 --- a/host/include/uhd/utils/msg_task.hpp +++ b/host/include/uhd/utils/msg_task.hpp @@ -10,58 +10,59 @@ #include <uhd/config.hpp> #include <uhd/transport/zero_copy.hpp> -#include <boost/shared_ptr.hpp> +#include <stdint.h> #include <boost/function.hpp> -#include <boost/utility.hpp> #include <boost/optional/optional.hpp> -#include <stdint.h> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> #include <vector> -namespace uhd{ - class UHD_API msg_task : boost::noncopyable{ - public: - typedef boost::shared_ptr<msg_task> sptr; - typedef std::vector<uint8_t> msg_payload_t; - typedef std::pair<uint32_t, msg_payload_t > msg_type_t; - typedef boost::function<boost::optional<msg_type_t>(void)> task_fcn_type; +namespace uhd { +class UHD_API msg_task : boost::noncopyable +{ +public: + typedef boost::shared_ptr<msg_task> sptr; + typedef std::vector<uint8_t> msg_payload_t; + typedef std::pair<uint32_t, msg_payload_t> msg_type_t; + typedef boost::function<boost::optional<msg_type_t>(void)> task_fcn_type; - /* - * During shutdown message queues for radio control cores might not be available anymore. - * Such stranded messages get pushed into a dump queue. - * With this function radio_ctrl_core can check if one of the messages meant for it got stranded. - */ - virtual msg_payload_t get_msg_from_dump_queue(uint32_t sid) = 0; + /* + * During shutdown message queues for radio control cores might not be available + * anymore. Such stranded messages get pushed into a dump queue. With this function + * radio_ctrl_core can check if one of the messages meant for it got stranded. + */ + virtual msg_payload_t get_msg_from_dump_queue(uint32_t sid) = 0; - UHD_INLINE static std::vector<uint8_t> buff_to_vector(uint8_t* p, size_t n) { - if(p and n > 0){ - std::vector<uint8_t> v(n); - memcpy(&v.front(), p, n); - return v; - } - return std::vector<uint8_t>(); - } + UHD_INLINE static std::vector<uint8_t> buff_to_vector(uint8_t* p, size_t n) + { + if (p and n > 0) { + std::vector<uint8_t> v(n); + memcpy(&v.front(), p, n); + return v; + } + return std::vector<uint8_t>(); + } - virtual ~msg_task(void) = 0; + virtual ~msg_task(void) = 0; - /*! - * Create a new task object with function callback. - * The task function callback will be run in a loop. - * until the thread is interrupted by the deconstructor. - * - * A function may return payload which is then pushed to - * a synchronized message queue. - * - * A task should return in a reasonable amount of time - * or may block forever under the following conditions: - * - The blocking call is interruptible. - * - The task polls the interrupt condition. - * - * \param task_fcn the task callback function - * \return a new task object - */ - static sptr make(const task_fcn_type &task_fcn); - }; -} //namespace uhd + /*! + * Create a new task object with function callback. + * The task function callback will be run in a loop. + * until the thread is interrupted by the deconstructor. + * + * A function may return payload which is then pushed to + * a synchronized message queue. + * + * A task should return in a reasonable amount of time + * or may block forever under the following conditions: + * - The blocking call is interruptible. + * - The task polls the interrupt condition. + * + * \param task_fcn the task callback function + * \return a new task object + */ + static sptr make(const task_fcn_type& task_fcn); +}; +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_MSG_TASK_HPP */ - diff --git a/host/include/uhd/utils/paths.hpp b/host/include/uhd/utils/paths.hpp index 341e0fa6c..035a4943d 100644 --- a/host/include/uhd/utils/paths.hpp +++ b/host/include/uhd/utils/paths.hpp @@ -9,9 +9,7 @@ #define INCLUDED_UHD_UTILS_PATHS_HPP #include <uhd/config.hpp> - #include <boost/filesystem.hpp> - #include <string> #include <vector> @@ -19,65 +17,67 @@ namespace fs = boost::filesystem; namespace uhd { - //! Get a string representing the system's temporary directory - UHD_API std::string get_tmp_path(void); +//! Get a string representing the system's temporary directory +UHD_API std::string get_tmp_path(void); - //! Get a string representing the system's appdata directory - UHD_API std::string get_app_path(void); +//! Get a string representing the system's appdata directory +UHD_API std::string get_app_path(void); - //! Get a string representing the system's pkg directory - UHD_API std::string get_pkg_path(void); +//! Get a string representing the system's pkg directory +UHD_API std::string get_pkg_path(void); - //! Get UHD library paths - UHD_API std::vector<fs::path> get_module_paths(void); +//! Get UHD library paths +UHD_API std::vector<fs::path> get_module_paths(void); - /*! Return the UHD images directory path. - * - * This function returns the UHD images installation path on this system. The - * returned directory path is guaranteed to exist (assuming a valid path is - * found). This function will look for a directory that exists using this - * order of precedence: - * - * 1) `UHD_IMAGES_DIR` environment variable - * 2) Any paths passed to this function via `search_paths' - * 3) UHD package path / share / uhd / images - * - * The `search_paths` parameter may contain Windows registry keys. If no - * directory is found, an empty string is returned. - * - * \param search_paths A comma-separated list of hints for paths to include. - * \returns A path string if one is found, or an empty string on failure. - */ - UHD_API std::string get_images_dir(const std::string &search_paths); +/*! Return the UHD images directory path. + * + * This function returns the UHD images installation path on this system. The + * returned directory path is guaranteed to exist (assuming a valid path is + * found). This function will look for a directory that exists using this + * order of precedence: + * + * 1) `UHD_IMAGES_DIR` environment variable + * 2) Any paths passed to this function via `search_paths' + * 3) UHD package path / share / uhd / images + * + * The `search_paths` parameter may contain Windows registry keys. If no + * directory is found, an empty string is returned. + * + * \param search_paths A comma-separated list of hints for paths to include. + * \returns A path string if one is found, or an empty string on failure. + */ +UHD_API std::string get_images_dir(const std::string& search_paths); - /*! Return the full path to particular UHD binary image. - * - * This function searches for the passed image name, and returns an absolute - * path to it. The returned path is guaranteed to exist. The caller can also - * provide a full path to the image in the argument, and this function will - * validate it and convert it to an absolute system path. - * - * \param image_name The name of the file to search for, or the full path. - * \param search_paths Hints / paths to use when calling `get_images_dir` - * \return the full system path to the file - * \throw exception uhd::io_error if the file was not found. - */ - UHD_API std::string find_image_path(const std::string &image_name, const std::string &search_paths = ""); +/*! Return the full path to particular UHD binary image. + * + * This function searches for the passed image name, and returns an absolute + * path to it. The returned path is guaranteed to exist. The caller can also + * provide a full path to the image in the argument, and this function will + * validate it and convert it to an absolute system path. + * + * \param image_name The name of the file to search for, or the full path. + * \param search_paths Hints / paths to use when calling `get_images_dir` + * \return the full system path to the file + * \throw exception uhd::io_error if the file was not found. + */ +UHD_API std::string find_image_path( + const std::string& image_name, const std::string& search_paths = ""); - /*! - * Search for the location of a particular UHD utility. - * The utility must be installed in the `uhd/utils` directory. - * \param name the name of the utility to search for - * \return the full system path to the given utility - */ - UHD_API std::string find_utility(const std::string &name); +/*! + * Search for the location of a particular UHD utility. + * The utility must be installed in the `uhd/utils` directory. + * \param name the name of the utility to search for + * \return the full system path to the given utility + */ +UHD_API std::string find_utility(const std::string& name); - /*! - * Return an error string recommending the user run the utility. - * The error string will include the full path to the utility to run. - * \return the message suggesting the use of the named utility. - */ - UHD_API std::string print_utility_error(const std::string &name, const std::string &args = ""); -} //namespace uhd +/*! + * Return an error string recommending the user run the utility. + * The error string will include the full path to the utility to run. + * \return the message suggesting the use of the named utility. + */ +UHD_API std::string print_utility_error( + const std::string& name, const std::string& args = ""); +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_PATHS_HPP */ diff --git a/host/include/uhd/utils/pimpl.hpp b/host/include/uhd/utils/pimpl.hpp index e536c3d0d..a19f4ddc2 100644 --- a/host/include/uhd/utils/pimpl.hpp +++ b/host/include/uhd/utils/pimpl.hpp @@ -30,7 +30,8 @@ * \param _name the name of the pimpl class */ #define UHD_PIMPL_DECL(_name) \ - struct _name; boost::shared_ptr<_name> + struct _name; \ + boost::shared_ptr<_name> /*! * Make an instance of a pimpl in a source file. @@ -39,7 +40,6 @@ * \param _name the name of the pimpl class * \param _args the constructor args for the pimpl */ -#define UHD_PIMPL_MAKE(_name, _args) \ - boost::shared_ptr<_name>(new _name _args) +#define UHD_PIMPL_MAKE(_name, _args) boost::shared_ptr<_name>(new _name _args) #endif /* INCLUDED_UHD_UTILS_PIMPL_HPP */ diff --git a/host/include/uhd/utils/platform.hpp b/host/include/uhd/utils/platform.hpp index bd5d19264..1d8d58b26 100644 --- a/host/include/uhd/utils/platform.hpp +++ b/host/include/uhd/utils/platform.hpp @@ -12,15 +12,15 @@ namespace uhd { - /* Returns the process ID of the current process */ - int32_t get_process_id(); +/* Returns the process ID of the current process */ +int32_t get_process_id(); - /* Returns a unique identifier for the current machine */ - uint32_t get_host_id(); +/* Returns a unique identifier for the current machine */ +uint32_t get_host_id(); - /* Get a unique identifier for the current machine and process */ - uint32_t get_process_hash(); +/* Get a unique identifier for the current machine and process */ +uint32_t get_process_hash(); -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_PLATFORM_HPP */ diff --git a/host/include/uhd/utils/safe_call.hpp b/host/include/uhd/utils/safe_call.hpp index e37014b71..2688c5d68 100644 --- a/host/include/uhd/utils/safe_call.hpp +++ b/host/include/uhd/utils/safe_call.hpp @@ -13,9 +13,9 @@ #include <uhd/utils/log.hpp> //! helper macro for safe call to produce warnings -#define _UHD_SAFE_CALL_WARNING(code, what) UHD_LOGGER_ERROR("UHD") << \ - UHD_THROW_SITE_INFO("Exception caught in safe-call.") + #code + " -> " + what \ -; +#define _UHD_SAFE_CALL_WARNING(code, what) \ + UHD_LOGGER_ERROR("UHD") << UHD_THROW_SITE_INFO("Exception caught in safe-call.") \ + + #code + " -> " + what; /*! * A safe-call catches all exceptions thrown by code, @@ -23,12 +23,12 @@ * Usage: UHD_SAFE_CALL(some_code_to_call();) * \param code the block of code to call safely */ -#define UHD_SAFE_CALL(code) \ - try{code} \ - catch(const std::exception &e){ \ - _UHD_SAFE_CALL_WARNING(code, e.what()); \ - } \ - catch(...){ \ +#define UHD_SAFE_CALL(code) \ + try { \ + code \ + } catch (const std::exception& e) { \ + _UHD_SAFE_CALL_WARNING(code, e.what()); \ + } catch (...) { \ _UHD_SAFE_CALL_WARNING(code, "unknown exception"); \ } diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp index 8261ad7d2..ca00a97dd 100644 --- a/host/include/uhd/utils/safe_main.hpp +++ b/host/include/uhd/utils/safe_main.hpp @@ -19,16 +19,19 @@ * \param _argc the declaration for argc * \param _argv the declaration for argv */ -#define UHD_SAFE_MAIN(_argc, _argv) _main(int, char*[]); \ -int main(int argc, char *argv[]){ \ - try { \ - return _main(argc, argv); \ - } catch(const std::exception &e) { \ - std::cerr << "Error: " << e.what() << std::endl; \ - } catch(...) { \ - std::cerr << "Error: unknown exception" << std::endl; \ - } \ - return ~0; \ -} int _main(_argc, _argv) +#define UHD_SAFE_MAIN(_argc, _argv) \ + _main(int, char* []); \ + int main(int argc, char* argv[]) \ + { \ + try { \ + return _main(argc, argv); \ + } catch (const std::exception& e) { \ + std::cerr << "Error: " << e.what() << std::endl; \ + } catch (...) { \ + std::cerr << "Error: unknown exception" << std::endl; \ + } \ + return ~0; \ + } \ + int _main(_argc, _argv) #endif /* INCLUDED_UHD_UTILS_SAFE_MAIN_HPP */ diff --git a/host/include/uhd/utils/soft_register.hpp b/host/include/uhd/utils/soft_register.hpp index fea4c0791..5a1d175e0 100644 --- a/host/include/uhd/utils/soft_register.hpp +++ b/host/include/uhd/utils/soft_register.hpp @@ -8,16 +8,16 @@ #ifndef INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP #define INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP -#include <stdint.h> -#include <boost/noncopyable.hpp> -#include <uhd/types/wb_iface.hpp> #include <uhd/exception.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/dirty_tracked.hpp> -#include <boost/thread/mutex.hpp> +#include <stdint.h> +#include <boost/foreach.hpp> +#include <boost/noncopyable.hpp> #include <boost/thread/locks.hpp> -#include <boost/unordered_map.hpp> +#include <boost/thread/mutex.hpp> #include <boost/tokenizer.hpp> -#include <boost/foreach.hpp> +#include <boost/unordered_map.hpp> #include <list> /*! \file soft_register.hpp @@ -43,7 +43,7 @@ namespace uhd { -//TODO: These hints were added to boost 1.53. +// TODO: These hints were added to boost 1.53. /** \brief hint for the branch prediction */ UHD_INLINE bool likely(bool expr) @@ -53,7 +53,7 @@ UHD_INLINE bool likely(bool expr) #else return expr; #endif - } +} /** \brief hint for the branch prediction */ UHD_INLINE bool unlikely(bool expr) @@ -75,45 +75,49 @@ UHD_INLINE bool unlikely(bool expr) typedef uint32_t soft_reg_field_t; namespace soft_reg_field { - UHD_INLINE size_t width(const soft_reg_field_t field) { - return (field & 0xFF); - } +UHD_INLINE size_t width(const soft_reg_field_t field) +{ + return (field & 0xFF); +} - UHD_INLINE size_t shift(const soft_reg_field_t field) { - return ((field >> 8) & 0xFF); - } +UHD_INLINE size_t shift(const soft_reg_field_t field) +{ + return ((field >> 8) & 0xFF); +} - template<typename data_t> - UHD_INLINE data_t mask(const soft_reg_field_t field) { - constexpr data_t ONE = static_cast<data_t>(1); - constexpr data_t ALL_ONES = ~static_cast<data_t>(0); - //Behavior for the left shift operation is undefined in C++ - //if the shift amount is >= bitwidth of the datatype - //So we treat that as a special case with a branch predicition hint - if (likely((sizeof(data_t)*8) != width(field))) { - return ((ONE<<width(field))-ONE)<<shift(field); - } else { - return ALL_ONES<<shift(field); - } +template <typename data_t> UHD_INLINE data_t mask(const soft_reg_field_t field) +{ + constexpr data_t ONE = static_cast<data_t>(1); + constexpr data_t ALL_ONES = ~static_cast<data_t>(0); + // Behavior for the left shift operation is undefined in C++ + // if the shift amount is >= bitwidth of the datatype + // So we treat that as a special case with a branch predicition hint + if (likely((sizeof(data_t) * 8) != width(field))) { + return ((ONE << width(field)) - ONE) << shift(field); + } else { + return ALL_ONES << shift(field); } } +} // namespace soft_reg_field -class soft_register_base : public boost::noncopyable { +class soft_register_base : public boost::noncopyable +{ public: virtual ~soft_register_base() {} virtual void initialize(wb_iface& iface, bool sync = false) = 0; - virtual void flush() = 0; - virtual void refresh() = 0; - virtual size_t get_bitwidth() = 0; - virtual bool is_readable() = 0; - virtual bool is_writable() = 0; + virtual void flush() = 0; + virtual void refresh() = 0; + virtual size_t get_bitwidth() = 0; + virtual bool is_readable() = 0; + virtual bool is_writable() = 0; /*! * Cast the soft_register generic reference to a more specific type */ template <typename soft_reg_t> - UHD_INLINE static soft_reg_t& cast(soft_register_base& reg) { + UHD_INLINE static soft_reg_t& cast(soft_register_base& reg) + { soft_reg_t* ptr = dynamic_cast<soft_reg_t*>(®); if (ptr) { return *ptr; @@ -130,33 +134,38 @@ enum soft_reg_flush_mode_t { OPTIMIZED_FLUSH, ALWAYS_FLUSH }; * Methods give convenient field-level access to soft-copy and the ability * to do read-modify-write operations. */ -template<typename reg_data_t, bool readable, bool writable> -class UHD_API soft_register_t : public soft_register_base { +template <typename reg_data_t, bool readable, bool writable> +class UHD_API soft_register_t : public soft_register_base +{ public: - typedef boost::shared_ptr< soft_register_t<reg_data_t, readable, writable> > sptr; + typedef boost::shared_ptr<soft_register_t<reg_data_t, readable, writable> > sptr; - //Reserved field. Represents all bits in the register. - UHD_DEFINE_SOFT_REG_FIELD(REGISTER, sizeof(reg_data_t)*8, 0); //[WIDTH-1:0] + // Reserved field. Represents all bits in the register. + UHD_DEFINE_SOFT_REG_FIELD(REGISTER, sizeof(reg_data_t) * 8, 0); //[WIDTH-1:0] /*! * Generic constructor for all soft_register types */ - soft_register_t( - wb_iface::wb_addr_type wr_addr, - wb_iface::wb_addr_type rd_addr, - soft_reg_flush_mode_t mode = ALWAYS_FLUSH): - _iface(NULL), _wr_addr(wr_addr), _rd_addr(rd_addr), _soft_copy(0), _flush_mode(mode) - {} + soft_register_t(wb_iface::wb_addr_type wr_addr, + wb_iface::wb_addr_type rd_addr, + soft_reg_flush_mode_t mode = ALWAYS_FLUSH) + : _iface(NULL) + , _wr_addr(wr_addr) + , _rd_addr(rd_addr) + , _soft_copy(0) + , _flush_mode(mode) + { + } /*! * Constructor for read-only, write-only registers and read-write registers * with rd_addr == wr_addr */ explicit soft_register_t( - wb_iface::wb_addr_type addr, - soft_reg_flush_mode_t mode = ALWAYS_FLUSH): - _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode) - {} + wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode = ALWAYS_FLUSH) + : _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode) + { + } /*! * Initialize the register when the underlying bus is usable. @@ -167,9 +176,11 @@ public: { _iface = &iface; - //Synchronize with hardware. For RW register, flush THEN refresh. - if (sync && writable) flush(); - if (sync && readable) refresh(); + // Synchronize with hardware. For RW register, flush THEN refresh. + if (sync && writable) + flush(); + if (sync && readable) + refresh(); } /*! @@ -179,8 +190,9 @@ public: */ UHD_INLINE void set(const soft_reg_field_t field, const reg_data_t value) { - _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field)) | - ((value << soft_reg_field::shift(field)) & soft_reg_field::mask<reg_data_t>(field)); + _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field)) + | ((value << soft_reg_field::shift(field)) + & soft_reg_field::mask<reg_data_t>(field)); } /*! @@ -189,7 +201,8 @@ public: */ UHD_INLINE reg_data_t get(const soft_reg_field_t field) { - return (_soft_copy & soft_reg_field::mask<reg_data_t>(field)) >> soft_reg_field::shift(field); + return (_soft_copy & soft_reg_field::mask<reg_data_t>(field)) + >> soft_reg_field::shift(field); } /*! @@ -198,9 +211,9 @@ public: UHD_INLINE void flush() { if (writable && _iface) { - //If optimized flush then poke only if soft copy is dirty - //If flush mode is ALWAYS, the dirty flag should get optimized - //out by the compiler because it is never read + // If optimized flush then poke only if soft copy is dirty + // If flush mode is ALWAYS, the dirty flag should get optimized + // out by the compiler because it is never read if (_flush_mode == ALWAYS_FLUSH || _soft_copy.is_dirty()) { if (get_bitwidth() <= 16) { _iface->poke16(_wr_addr, static_cast<uint16_t>(_soft_copy)); @@ -209,12 +222,14 @@ public: } else if (get_bitwidth() <= 64) { _iface->poke64(_wr_addr, static_cast<uint64_t>(_soft_copy)); } else { - throw uhd::not_implemented_error("soft_register only supports up to 64 bits."); + throw uhd::not_implemented_error( + "soft_register only supports up to 64 bits."); } _soft_copy.mark_clean(); } } else { - throw uhd::not_implemented_error("soft_register is not writable or uninitialized."); + throw uhd::not_implemented_error( + "soft_register is not writable or uninitialized."); } } @@ -231,11 +246,13 @@ public: } else if (get_bitwidth() <= 64) { _soft_copy = static_cast<reg_data_t>(_iface->peek64(_rd_addr)); } else { - throw uhd::not_implemented_error("soft_register only supports up to 64 bits."); + throw uhd::not_implemented_error( + "soft_register only supports up to 64 bits."); } _soft_copy.mark_clean(); } else { - throw uhd::not_implemented_error("soft_register is not readable or uninitialized."); + throw uhd::not_implemented_error( + "soft_register is not readable or uninitialized."); } } @@ -283,34 +300,37 @@ public: } private: - wb_iface* _iface; - const wb_iface::wb_addr_type _wr_addr; - const wb_iface::wb_addr_type _rd_addr; - dirty_tracked<reg_data_t> _soft_copy; - const soft_reg_flush_mode_t _flush_mode; + wb_iface* _iface; + const wb_iface::wb_addr_type _wr_addr; + const wb_iface::wb_addr_type _rd_addr; + dirty_tracked<reg_data_t> _soft_copy; + const soft_reg_flush_mode_t _flush_mode; }; /*! * A synchronized soft register object. * All operations in the synchronized register are serialized. */ -template<typename reg_data_t, bool readable, bool writable> -class UHD_API soft_register_sync_t : public soft_register_t<reg_data_t, readable, writable> { +template <typename reg_data_t, bool readable, bool writable> +class UHD_API soft_register_sync_t + : public soft_register_t<reg_data_t, readable, writable> +{ public: - typedef boost::shared_ptr< soft_register_sync_t<reg_data_t, readable, writable> > sptr; + typedef boost::shared_ptr<soft_register_sync_t<reg_data_t, readable, writable> > sptr; - soft_register_sync_t( - wb_iface::wb_addr_type wr_addr, - wb_iface::wb_addr_type rd_addr, - soft_reg_flush_mode_t mode = ALWAYS_FLUSH): - soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode), _mutex() - {} + soft_register_sync_t(wb_iface::wb_addr_type wr_addr, + wb_iface::wb_addr_type rd_addr, + soft_reg_flush_mode_t mode = ALWAYS_FLUSH) + : soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode) + , _mutex() + { + } explicit soft_register_sync_t( - wb_iface::wb_addr_type addr, - soft_reg_flush_mode_t mode = ALWAYS_FLUSH): - soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex() - {} + wb_iface::wb_addr_type addr, soft_reg_flush_mode_t mode = ALWAYS_FLUSH) + : soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex() + { + } UHD_INLINE void initialize(wb_iface& iface, bool sync = false) { @@ -370,27 +390,27 @@ private: * */ -//16-bit shortcuts -typedef soft_register_t<uint16_t, false, true> soft_reg16_wo_t; -typedef soft_register_t<uint16_t, true, false> soft_reg16_ro_t; -typedef soft_register_t<uint16_t, true, true> soft_reg16_rw_t; -typedef soft_register_sync_t<uint16_t, false, true> soft_reg16_wo_sync_t; -typedef soft_register_sync_t<uint16_t, true, false> soft_reg16_ro_sync_t; -typedef soft_register_sync_t<uint16_t, true, true> soft_reg16_rw_sync_t; -//32-bit shortcuts -typedef soft_register_t<uint32_t, false, true> soft_reg32_wo_t; -typedef soft_register_t<uint32_t, true, false> soft_reg32_ro_t; -typedef soft_register_t<uint32_t, true, true> soft_reg32_rw_t; -typedef soft_register_sync_t<uint32_t, false, true> soft_reg32_wo_sync_t; -typedef soft_register_sync_t<uint32_t, true, false> soft_reg32_ro_sync_t; -typedef soft_register_sync_t<uint32_t, true, true> soft_reg32_rw_sync_t; -//64-bit shortcuts -typedef soft_register_t<uint64_t, false, true> soft_reg64_wo_t; -typedef soft_register_t<uint64_t, true, false> soft_reg64_ro_t; -typedef soft_register_t<uint64_t, true, true> soft_reg64_rw_t; -typedef soft_register_sync_t<uint64_t, false, true> soft_reg64_wo_sync_t; -typedef soft_register_sync_t<uint64_t, true, false> soft_reg64_ro_sync_t; -typedef soft_register_sync_t<uint64_t, true, true> soft_reg64_rw_sync_t; +// 16-bit shortcuts +typedef soft_register_t<uint16_t, false, true> soft_reg16_wo_t; +typedef soft_register_t<uint16_t, true, false> soft_reg16_ro_t; +typedef soft_register_t<uint16_t, true, true> soft_reg16_rw_t; +typedef soft_register_sync_t<uint16_t, false, true> soft_reg16_wo_sync_t; +typedef soft_register_sync_t<uint16_t, true, false> soft_reg16_ro_sync_t; +typedef soft_register_sync_t<uint16_t, true, true> soft_reg16_rw_sync_t; +// 32-bit shortcuts +typedef soft_register_t<uint32_t, false, true> soft_reg32_wo_t; +typedef soft_register_t<uint32_t, true, false> soft_reg32_ro_t; +typedef soft_register_t<uint32_t, true, true> soft_reg32_rw_t; +typedef soft_register_sync_t<uint32_t, false, true> soft_reg32_wo_sync_t; +typedef soft_register_sync_t<uint32_t, true, false> soft_reg32_ro_sync_t; +typedef soft_register_sync_t<uint32_t, true, true> soft_reg32_rw_sync_t; +// 64-bit shortcuts +typedef soft_register_t<uint64_t, false, true> soft_reg64_wo_t; +typedef soft_register_t<uint64_t, true, false> soft_reg64_ro_t; +typedef soft_register_t<uint64_t, true, true> soft_reg64_rw_t; +typedef soft_register_sync_t<uint64_t, false, true> soft_reg64_wo_sync_t; +typedef soft_register_sync_t<uint64_t, true, false> soft_reg64_ro_sync_t; +typedef soft_register_sync_t<uint64_t, true, true> soft_reg64_rw_sync_t; /* @@ -424,7 +444,7 @@ typedef soft_register_sync_t<uint64_t, true, true> soft_reg64_rw_sync_t; reg_obj->write(example_reg_t::FIELD2, 0x1234); } */ -} +} // namespace uhd //================================================================== // Soft Register Map and Database Definition @@ -432,14 +452,15 @@ typedef soft_register_sync_t<uint64_t, true, true> soft_reg64_rw_sync_t; namespace uhd { -class UHD_API soft_regmap_accessor_t { +class UHD_API soft_regmap_accessor_t +{ public: typedef boost::shared_ptr<soft_regmap_accessor_t> sptr; - virtual ~soft_regmap_accessor_t() {}; + virtual ~soft_regmap_accessor_t(){}; virtual soft_register_base& lookup(const std::string& path) const = 0; - virtual std::vector<std::string> enumerate() const = 0; - virtual const std::string& get_name() const = 0; + virtual std::vector<std::string> enumerate() const = 0; + virtual const std::string& get_name() const = 0; }; /*! @@ -452,15 +473,19 @@ public: * Methods give convenient field-level access to soft-copy and the ability * to do read-modify-write operations. */ -class UHD_API soft_regmap_t : public soft_regmap_accessor_t, public boost::noncopyable { +class UHD_API soft_regmap_t : public soft_regmap_accessor_t, public boost::noncopyable +{ public: soft_regmap_t(const std::string& name) : _name(name) {} - virtual ~soft_regmap_t() {}; + virtual ~soft_regmap_t(){}; /*! * Get the name of this register map */ - virtual UHD_INLINE const std::string& get_name() const { return _name; } + virtual UHD_INLINE const std::string& get_name() const + { + return _name; + } /*! * Initialize all registers in this register map using a bus. @@ -468,9 +493,10 @@ public: * The order of initialization is the same as the order in * which registers were added to the map. */ - void initialize(wb_iface& iface, bool sync = false) { + void initialize(wb_iface& iface, bool sync = false) + { boost::lock_guard<boost::mutex> lock(_mutex); - BOOST_FOREACH(soft_register_base* reg, _reglist) { + BOOST_FOREACH (soft_register_base* reg, _reglist) { reg->initialize(iface, sync); } } @@ -480,9 +506,10 @@ public: * The order of writing is the same as the order in * which registers were added to the map. */ - void flush() { + void flush() + { boost::lock_guard<boost::mutex> lock(_mutex); - BOOST_FOREACH(soft_register_base* reg, _reglist) { + BOOST_FOREACH (soft_register_base* reg, _reglist) { reg->flush(); } } @@ -492,9 +519,10 @@ public: * The order of reading is the same as the order in * which registers were added to the map. */ - void refresh() { + void refresh() + { boost::lock_guard<boost::mutex> lock(_mutex); - BOOST_FOREACH(soft_register_base* reg, _reglist) { + BOOST_FOREACH (soft_register_base* reg, _reglist) { reg->refresh(); } } @@ -503,7 +531,8 @@ public: * Lookup a register object by name. * If a register with "name" is not found, runtime_error is thrown */ - virtual soft_register_base& lookup(const std::string& name) const { + virtual soft_register_base& lookup(const std::string& name) const + { regmap_t::const_iterator iter = _regmap.find(name); if (iter != _regmap.end()) { return *(iter->second); @@ -516,9 +545,10 @@ public: * Enumerate all the registers in this map. * Return fully qualified paths. */ - virtual std::vector<std::string> enumerate() const { + virtual std::vector<std::string> enumerate() const + { std::vector<std::string> temp; - BOOST_FOREACH(const regmap_t::value_type& reg, _regmap) { + BOOST_FOREACH (const regmap_t::value_type& reg, _regmap) { temp.push_back(_name + "/" + reg.first); } return temp; @@ -526,19 +556,23 @@ public: protected: enum visibility_t { - PUBLIC, //Is accessible through the soft_regmap_accessor_t interface - PRIVATE //Is NOT accessible through the soft_regmap_accessor_t interface + PUBLIC, // Is accessible through the soft_regmap_accessor_t interface + PRIVATE // Is NOT accessible through the soft_regmap_accessor_t interface }; /*! * Add a register to this map with an identifier "name" and visibility */ - UHD_INLINE void add_to_map(soft_register_base& reg, const std::string& name, const visibility_t visible = PRIVATE) { + UHD_INLINE void add_to_map(soft_register_base& reg, + const std::string& name, + const visibility_t visible = PRIVATE) + { boost::lock_guard<boost::mutex> lock(_mutex); if (visible == PUBLIC) { - //Only add to the map if this register is publicly visible + // Only add to the map if this register is publicly visible if (not _regmap.insert(regmap_t::value_type(name, ®)).second) { - throw uhd::assertion_error("cannot add two registers with the same name to regmap: " + name); + throw uhd::assertion_error( + "cannot add two registers with the same name to regmap: " + name); } } _reglist.push_back(®); @@ -546,12 +580,12 @@ protected: private: typedef boost::unordered_map<std::string, soft_register_base*> regmap_t; - typedef std::list<soft_register_base*> reglist_t; + typedef std::list<soft_register_base*> reglist_t; - const std::string _name; - regmap_t _regmap; //For lookups - reglist_t _reglist; //To maintain order - boost::mutex _mutex; + const std::string _name; + regmap_t _regmap; // For lookups + reglist_t _reglist; // To maintain order + boost::mutex _mutex; }; @@ -561,7 +595,8 @@ private: * fashion. * A regmap_db *does not* manage storage for regmaps. It is simply a wrapper. */ -class UHD_API soft_regmap_db_t : public soft_regmap_accessor_t, public boost::noncopyable { +class UHD_API soft_regmap_db_t : public soft_regmap_accessor_t, public boost::noncopyable +{ public: typedef boost::shared_ptr<soft_regmap_db_t> sptr; @@ -578,12 +613,16 @@ public: /*! * Get the name of this register map */ - const std::string& get_name() const { return _name; } + const std::string& get_name() const + { + return _name; + } /*! * Add a regmap to this map with an identifier "name" and visibility */ - void add(soft_regmap_t& regmap) { + void add(soft_regmap_t& regmap) + { boost::lock_guard<boost::mutex> lock(_mutex); _regmaps.push_back(®map); } @@ -591,7 +630,8 @@ public: /*! * Add a level of regmap_db to this map with an identifier "name" and visibility */ - void add(soft_regmap_db_t& db) { + void add(soft_regmap_db_t& db) + { boost::lock_guard<boost::mutex> lock(_mutex); if (&db == this) { throw uhd::assertion_error("cannot add regmap db to itself" + _name); @@ -612,32 +652,33 @@ public: */ soft_register_base& lookup(const std::string& path) const { - //Turn the slash separated path string into tokens + // Turn the slash separated path string into tokens std::list<std::string> tokens; - BOOST_FOREACH( - const std::string& node, - boost::tokenizer< boost::char_separator<char> >(path, boost::char_separator<char>("/"))) - { + BOOST_FOREACH (const std::string& node, + boost::tokenizer<boost::char_separator<char> >( + path, boost::char_separator<char>("/"))) { tokens.push_back(node); } - if ((tokens.size() > 2 && tokens.front() == _name) || //If this is a nested DB - (tokens.size() > 1 && _name == "")) { //If this is a top-level DB - if (_name != "") tokens.pop_front(); - if (tokens.size() == 2) { //2 tokens => regmap/register path - BOOST_FOREACH(const soft_regmap_accessor_t* regmap, _regmaps) { + if ((tokens.size() > 2 && tokens.front() == _name) || // If this is a nested DB + (tokens.size() > 1 && _name == "")) { // If this is a top-level DB + if (_name != "") + tokens.pop_front(); + if (tokens.size() == 2) { // 2 tokens => regmap/register path + BOOST_FOREACH (const soft_regmap_accessor_t* regmap, _regmaps) { if (regmap->get_name() == tokens.front()) { return regmap->lookup(tokens.back()); } } throw uhd::runtime_error("could not find register map: " + path); - } else if (not _regmap_dbs.empty()) { //>2 tokens => <1 or more dbs>/regmap/register - //Reconstruct path from tokens + } else if (not _regmap_dbs + .empty()) { //>2 tokens => <1 or more dbs>/regmap/register + // Reconstruct path from tokens std::string newpath; - BOOST_FOREACH(const std::string& node, tokens) { + BOOST_FOREACH (const std::string& node, tokens) { newpath += ("/" + node); } - //Dispatch path to hierarchical DB - BOOST_FOREACH(const soft_regmap_accessor_t* db, _regmap_dbs) { + // Dispatch path to hierarchical DB + BOOST_FOREACH (const soft_regmap_accessor_t* db, _regmap_dbs) { try { return db->lookup(newpath.substr(1)); } catch (std::exception&) { @@ -652,13 +693,14 @@ public: /*! * Enumerate the paths of all registers that this DB can access */ - virtual std::vector<std::string> enumerate() const { + virtual std::vector<std::string> enumerate() const + { std::vector<std::string> paths; - BOOST_FOREACH(const soft_regmap_accessor_t* regmap, _regmaps) { + BOOST_FOREACH (const soft_regmap_accessor_t* regmap, _regmaps) { const std::vector<std::string>& regs = regmap->enumerate(); paths.insert(paths.end(), regs.begin(), regs.end()); } - BOOST_FOREACH(const soft_regmap_accessor_t* db, _regmap_dbs) { + BOOST_FOREACH (const soft_regmap_accessor_t* db, _regmap_dbs) { const std::vector<std::string>& regs = db->enumerate(); paths.insert(paths.end(), regs.begin(), regs.end()); } @@ -668,12 +710,12 @@ public: private: typedef std::list<soft_regmap_accessor_t*> db_t; - const std::string _name; - db_t _regmaps; - db_t _regmap_dbs; - boost::mutex _mutex; + const std::string _name; + db_t _regmaps; + db_t _regmap_dbs; + boost::mutex _mutex; }; -} //namespace uhd +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP */ diff --git a/host/include/uhd/utils/static.hpp b/host/include/uhd/utils/static.hpp index 3cde74b96..6a6f24721 100644 --- a/host/include/uhd/utils/static.hpp +++ b/host/include/uhd/utils/static.hpp @@ -16,21 +16,27 @@ * \param _x the name of the defined function * \return a reference to the lazy instance */ -#define UHD_SINGLETON_FCN(_t, _x) static _t &_x(){static _t _x; return _x;} +#define UHD_SINGLETON_FCN(_t, _x) \ + static _t& _x() \ + { \ + static _t _x; \ + return _x; \ + } /*! * Defines a static code block that will be called before main() * The static block will catch and print exceptions to std error. * \param _x the unique name of the fixture (unique per source) */ -#define UHD_STATIC_BLOCK(_x) \ - void _x(void); \ +#define UHD_STATIC_BLOCK(_x) \ + void _x(void); \ static _uhd_static_fixture _x##_fixture(&_x, #_x); \ void _x(void) //! Helper for static block, constructor calls function -struct UHD_API _uhd_static_fixture{ - _uhd_static_fixture(void (*)(void), const char *); +struct UHD_API _uhd_static_fixture +{ + _uhd_static_fixture(void (*)(void), const char*); }; #endif /* INCLUDED_UHD_UTILS_STATIC_HPP */ diff --git a/host/include/uhd/utils/tasks.hpp b/host/include/uhd/utils/tasks.hpp index d1245616c..5131fa028 100644 --- a/host/include/uhd/utils/tasks.hpp +++ b/host/include/uhd/utils/tasks.hpp @@ -10,35 +10,32 @@ #define INCLUDED_UHD_UTILS_TASKS_HPP #include <uhd/config.hpp> -#include <boost/shared_ptr.hpp> #include <boost/function.hpp> +#include <boost/shared_ptr.hpp> #include <boost/utility.hpp> -namespace uhd{ +namespace uhd { - class UHD_API task : boost::noncopyable{ - public: - typedef boost::shared_ptr<task> sptr; - typedef boost::function<void(void)> task_fcn_type; +class UHD_API task : boost::noncopyable +{ +public: + typedef boost::shared_ptr<task> sptr; + typedef boost::function<void(void)> task_fcn_type; - /*! - * Create a new task object with function callback. - * The task function callback will be run in a loop. - * until the thread is interrupted by the destructor. - * - * A task should return in a reasonable amount of time. - * It may not block, or the destructor will also block. - * - * \param task_fcn the task callback function - * \param name Task name. Will be used as a thread name. - * \return a new task object - */ - static sptr make( - const task_fcn_type &task_fcn, - const std::string &name="" - ); - }; -} //namespace uhd + /*! + * Create a new task object with function callback. + * The task function callback will be run in a loop. + * until the thread is interrupted by the destructor. + * + * A task should return in a reasonable amount of time. + * It may not block, or the destructor will also block. + * + * \param task_fcn the task callback function + * \param name Task name. Will be used as a thread name. + * \return a new task object + */ + static sptr make(const task_fcn_type& task_fcn, const std::string& name = ""); +}; +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_TASKS_HPP */ - diff --git a/host/include/uhd/utils/thread.hpp b/host/include/uhd/utils/thread.hpp index 5251d341e..c7358040e 100644 --- a/host/include/uhd/utils/thread.hpp +++ b/host/include/uhd/utils/thread.hpp @@ -12,49 +12,42 @@ #include <boost/thread/thread.hpp> #include <string> -namespace uhd{ - - static const float default_thread_priority = float(0.5); - - /*! - * Set the scheduling priority on the current thread. - * - * A new thread or calling process should make this call - * with the defaults this to enable realtime scheduling. - * - * A priority of zero corresponds to normal priority. - * Positive priority values are higher than normal. - * Negative priority values are lower than normal. - * - * \param priority a value between -1 and 1 - * \param realtime true to use realtime mode - * \throw exception on set priority failure - */ - UHD_API void set_thread_priority( - float priority = default_thread_priority, - bool realtime = true - ); - - /*! - * Set the scheduling priority on the current thread. - * Same as set_thread_priority but does not throw on failure. - * \return true on success, false on failure - */ - UHD_API bool set_thread_priority_safe( - float priority = default_thread_priority, - bool realtime = true - ); - - /*! - * Set the thread name on the given boost thread. - * \param thread pointer to a boost thread - * \param name thread name with maximum length of 16 characters - */ - UHD_API void set_thread_name( - boost::thread *thread, - const std::string &name - ); - -} //namespace uhd +namespace uhd { + +static const float default_thread_priority = float(0.5); + +/*! + * Set the scheduling priority on the current thread. + * + * A new thread or calling process should make this call + * with the defaults this to enable realtime scheduling. + * + * A priority of zero corresponds to normal priority. + * Positive priority values are higher than normal. + * Negative priority values are lower than normal. + * + * \param priority a value between -1 and 1 + * \param realtime true to use realtime mode + * \throw exception on set priority failure + */ +UHD_API void set_thread_priority( + float priority = default_thread_priority, bool realtime = true); + +/*! + * Set the scheduling priority on the current thread. + * Same as set_thread_priority but does not throw on failure. + * \return true on success, false on failure + */ +UHD_API bool set_thread_priority_safe( + float priority = default_thread_priority, bool realtime = true); + +/*! + * Set the thread name on the given boost thread. + * \param thread pointer to a boost thread + * \param name thread name with maximum length of 16 characters + */ +UHD_API void set_thread_name(boost::thread* thread, const std::string& name); + +} // namespace uhd #endif /* INCLUDED_UHD_UTILS_THREAD_HPP */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp index 8fd82cbc8..6a14f3976 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp @@ -6,93 +6,79 @@ #include "magnesium_ad9371_iface.hpp" #include <uhd/utils/log.hpp> -#include <uhd/utils/log.hpp> using namespace uhd; namespace { - /*! Return a valid 'which' string for use with AD9371 API calls - * - * These strings take the form of "RX1", "TX2", ... - */ - std::string _get_which( - const direction_t dir, - const size_t chan - ) { - UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); - UHD_ASSERT_THROW(chan == 0 or chan == 1); - return str(boost::format("%s%d") - % (dir == RX_DIRECTION ? "RX" : "TX") - % (chan+1) - ); - } +/*! Return a valid 'which' string for use with AD9371 API calls + * + * These strings take the form of "RX1", "TX2", ... + */ +std::string _get_which(const direction_t dir, const size_t chan) +{ + UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); + UHD_ASSERT_THROW(chan == 0 or chan == 1); + return str(boost::format("%s%d") % (dir == RX_DIRECTION ? "RX" : "TX") % (chan + 1)); } +} // namespace /****************************************************************************** * Structors *****************************************************************************/ magnesium_ad9371_iface::magnesium_ad9371_iface( - uhd::rpc_client::sptr rpcc, - const size_t slot_idx -) : _rpcc(rpcc) - , _slot_idx(slot_idx) - , _rpc_prefix((slot_idx == 0) ? "db_0_" : "db_1_") - , _log_prefix((slot_idx == 0) ? "AD9371-0" : "AD9371-1") + uhd::rpc_client::sptr rpcc, const size_t slot_idx) + : _rpcc(rpcc) + , _slot_idx(slot_idx) + , _rpc_prefix((slot_idx == 0) ? "db_0_" : "db_1_") + , _log_prefix((slot_idx == 0) ? "AD9371-0" : "AD9371-1") { UHD_LOG_TRACE(_log_prefix, - "Initialized controls with RPC prefix " << _rpc_prefix << - " for slot " << _slot_idx); + "Initialized controls with RPC prefix " << _rpc_prefix << " for slot " + << _slot_idx); } double magnesium_ad9371_iface::set_frequency( - const double freq, - const size_t chan, - const direction_t dir -) { + const double freq, const size_t chan, const direction_t dir) +{ // Note: This sets the frequency for both channels (1 and 2). - auto which = _get_which(dir, chan); + auto which = _get_which(dir, chan); auto actual_freq = request<double>("set_freq", which, freq, false); - UHD_LOG_TRACE(_log_prefix, - _rpc_prefix << "set_freq returned " << actual_freq); + UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "set_freq returned " << actual_freq); return actual_freq; } double magnesium_ad9371_iface::set_gain( - const double gain, - const size_t chan, - const direction_t dir -) { - auto which = _get_which(dir, chan); + const double gain, const size_t chan, const direction_t dir) +{ + auto which = _get_which(dir, chan); auto retval = request<double>("set_gain", which, gain); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "set_gain returned " << retval); return retval; - //return 0.0; + // return 0.0; } -double magnesium_ad9371_iface::set_master_clock_rate( - const double freq -) { +double magnesium_ad9371_iface::set_master_clock_rate(const double freq) +{ const auto actual_freq = request<double>("set_master_clock_rate", freq); - UHD_LOG_TRACE(_log_prefix, - _rpc_prefix << "set_master_clock_rate returned successfully"); + UHD_LOG_TRACE( + _log_prefix, _rpc_prefix << "set_master_clock_rate returned successfully"); return actual_freq; } -double magnesium_ad9371_iface::set_bandwidth(const double bandwidth, const size_t chan, const direction_t dir) +double magnesium_ad9371_iface::set_bandwidth( + const double bandwidth, const size_t chan, const direction_t dir) { auto const which = _get_which(dir, chan); - auto retval = request<double>("set_bw_filter", which, bandwidth); + auto retval = request<double>("set_bw_filter", which, bandwidth); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "set_bw_filter returned " << retval); return retval; } -double magnesium_ad9371_iface::get_frequency( - const size_t chan, - const direction_t dir -) { - auto which = _get_which(dir, chan); +double magnesium_ad9371_iface::get_frequency(const size_t chan, const direction_t dir) +{ + auto which = _get_which(dir, chan); auto retval = request<double>("get_freq", which); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "get_freq returned " << retval); return retval; @@ -100,13 +86,14 @@ double magnesium_ad9371_iface::get_frequency( double magnesium_ad9371_iface::get_gain(const size_t chan, const direction_t dir) { - auto which = _get_which(dir, chan); + auto which = _get_which(dir, chan); auto retval = request<double>("get_gain", which); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "get_gain returned " << retval); return retval; } -double magnesium_ad9371_iface::get_bandwidth(const size_t /*chan*/, const direction_t /*dir*/) +double magnesium_ad9371_iface::get_bandwidth( + const size_t /*chan*/, const direction_t /*dir*/) { // TODO: implement UHD_LOG_WARNING(_log_prefix, "Ignoring attempt to get bandwidth"); @@ -114,23 +101,20 @@ double magnesium_ad9371_iface::get_bandwidth(const size_t /*chan*/, const direct } std::string magnesium_ad9371_iface::set_lo_source( - const std::string &source, - const uhd::direction_t dir -) { + const std::string& source, const uhd::direction_t dir) +{ // There is only one LO for 2 channels. Using channel 0 for 'which' - auto which = _get_which(dir, 0); + auto which = _get_which(dir, 0); auto retval = request<std::string>("set_lo_source", which, source); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "set_lo_source returned " << retval); return retval; } -std::string magnesium_ad9371_iface::get_lo_source( - const uhd::direction_t dir -) { +std::string magnesium_ad9371_iface::get_lo_source(const uhd::direction_t dir) +{ // There is only one LO for 2 channels. Using channel 0 for 'which' - auto which = _get_which(dir, 0); + auto which = _get_which(dir, 0); auto retval = request<std::string>("get_lo_source", which); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "get_lo_source returned " << retval); return retval; } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp index acfecf2df..245c302ba 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp @@ -17,56 +17,27 @@ class magnesium_ad9371_iface public: using uptr = std::unique_ptr<magnesium_ad9371_iface>; - magnesium_ad9371_iface( - uhd::rpc_client::sptr rpcc, - const size_t slot_idx - ); + magnesium_ad9371_iface(uhd::rpc_client::sptr rpcc, const size_t slot_idx); double set_frequency( - const double freq, - const size_t chan, - const uhd::direction_t dir - ); - - double get_frequency( - const size_t chan, - const uhd::direction_t dir - ); - - double set_gain( - const double gain, - const size_t chan, - const uhd::direction_t dir - ); - - double get_gain( - const size_t chan, - const uhd::direction_t dir - ); - - double set_master_clock_rate( - const double freq - ); + const double freq, const size_t chan, const uhd::direction_t dir); + + double get_frequency(const size_t chan, const uhd::direction_t dir); + + double set_gain(const double gain, const size_t chan, const uhd::direction_t dir); + + double get_gain(const size_t chan, const uhd::direction_t dir); + + double set_master_clock_rate(const double freq); double set_bandwidth( - const double bandwidth, - const size_t chan, - const uhd::direction_t dir - ); + const double bandwidth, const size_t chan, const uhd::direction_t dir); - double get_bandwidth( - const size_t chan, - const uhd::direction_t dir - ); + double get_bandwidth(const size_t chan, const uhd::direction_t dir); - std::string set_lo_source( - const std::string &source, - const uhd::direction_t dir - ); + std::string set_lo_source(const std::string& source, const uhd::direction_t dir); - std::string get_lo_source( - const uhd::direction_t dir - ); + std::string get_lo_source(const uhd::direction_t dir); private: /*! Shorthand to perform an RPC request. Saves some typing. @@ -76,9 +47,7 @@ private: { UHD_LOG_TRACE(_log_prefix, "[RPC] Calling " << func_name); return _rpcc->request_with_token<return_type>( - _rpc_prefix + func_name, - std::forward<Args>(args)... - ); + _rpc_prefix + func_name, std::forward<Args>(args)...); }; //! Reference to the RPC client @@ -92,7 +61,6 @@ private: //! Logger prefix const std::string _log_prefix; - }; #endif /* INCLUDED_LIBUHD_RFNOC_MAGNESIUM_AD9371_IFACE_HPP */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp b/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp index 656543653..4792dcac6 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp @@ -6,8 +6,8 @@ // The band plan -#include "magnesium_radio_ctrl_impl.hpp" #include "magnesium_constants.hpp" +#include "magnesium_radio_ctrl_impl.hpp" #include <uhd/utils/math.hpp> /* @@ -43,66 +43,67 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - /* Note on the RX filter bank: - * - * The RX path has 7 bands, which we call BAND0 through BAND7. BAND0 is the - * lowest frequency band (it goes through F44, the 490 MHz low pass filter, - * on the first channel). BAND7 is the highest frequency band, it goes - * through the 2.7 GHz high pass filter (F43 on the first channel). - * - * For all frequencies, there are gain values where we bypass the filter - * bank. In this case, the band setting does not apply (does not have any - * meaning). - * - * The lowband, when not disabling the filter bank, always goes through - * BAND0, but there are non-lowband frequencies which can also go through - * BAND0. - * - * The following constants define lower cutoff frequencies for each band. - * BAND0 does not have a lower cutoff frequency, it is implied by - * MAGNESIUM_MIN_FREQ. MAGNESIUM_RX_BAND1_MIN_FREQ is the cutover frequency - * for switching from BAND0 to BAND1, and so on. - * - * Bands 1-6 have both high- and low-pass filters (effectively band - * passes). Frequencies need to be chosen to allow as much of the full - * bandwidth through unattenuated. - */ - constexpr double MAGNESIUM_RX_BAND1_MIN_FREQ = 430e6; - constexpr double MAGNESIUM_RX_BAND2_MIN_FREQ = 600e6; - constexpr double MAGNESIUM_RX_BAND3_MIN_FREQ = 1050e6; - constexpr double MAGNESIUM_RX_BAND4_MIN_FREQ = 1600e6; - constexpr double MAGNESIUM_RX_BAND5_MIN_FREQ = 2100e6; - constexpr double MAGNESIUM_RX_BAND6_MIN_FREQ = 2700e6; +/* Note on the RX filter bank: + * + * The RX path has 7 bands, which we call BAND0 through BAND7. BAND0 is the + * lowest frequency band (it goes through F44, the 490 MHz low pass filter, + * on the first channel). BAND7 is the highest frequency band, it goes + * through the 2.7 GHz high pass filter (F43 on the first channel). + * + * For all frequencies, there are gain values where we bypass the filter + * bank. In this case, the band setting does not apply (does not have any + * meaning). + * + * The lowband, when not disabling the filter bank, always goes through + * BAND0, but there are non-lowband frequencies which can also go through + * BAND0. + * + * The following constants define lower cutoff frequencies for each band. + * BAND0 does not have a lower cutoff frequency, it is implied by + * MAGNESIUM_MIN_FREQ. MAGNESIUM_RX_BAND1_MIN_FREQ is the cutover frequency + * for switching from BAND0 to BAND1, and so on. + * + * Bands 1-6 have both high- and low-pass filters (effectively band + * passes). Frequencies need to be chosen to allow as much of the full + * bandwidth through unattenuated. + */ +constexpr double MAGNESIUM_RX_BAND1_MIN_FREQ = 430e6; +constexpr double MAGNESIUM_RX_BAND2_MIN_FREQ = 600e6; +constexpr double MAGNESIUM_RX_BAND3_MIN_FREQ = 1050e6; +constexpr double MAGNESIUM_RX_BAND4_MIN_FREQ = 1600e6; +constexpr double MAGNESIUM_RX_BAND5_MIN_FREQ = 2100e6; +constexpr double MAGNESIUM_RX_BAND6_MIN_FREQ = 2700e6; - /* Note on the TX filter bank: - * - * The TX path has 4 bands, which we call BAND0 through BAND3. - * For all frequencies, there are gain values where we bypass the filter - * bank. In this case, the band setting does not apply (does not have any - * meaning). - * - * The lowband, when not disabling the filter bank, always goes through - * BAND0, but there are non-lowband frequencies which can also go through - * BAND0. - * - * The following constants define lower cutoff frequencies for each band. - * BAND0 does not have a lower cutoff frequency, it is implied by - * MAGNESIUM_MIN_FREQ. MAGNESIUM_TX_BAND1_MIN_FREQ is the cutover frequency - * for switching from BAND0 to BAND1, and so on. - * - * On current Magnesium revisions, all filters on the TX filter bank are - * low pass filters (no high pass filters). - * Frequencies need to be chosen to allow as much of the full bandwidth - * through unattenuated (so don't go all the way up to the cutoff frequency - * of that filter, OK). - */ - constexpr double MAGNESIUM_TX_BAND1_MIN_FREQ = 723.17e6; - constexpr double MAGNESIUM_TX_BAND2_MIN_FREQ = 1623.17e6; - constexpr double MAGNESIUM_TX_BAND3_MIN_FREQ = 3323.17e6; -} +/* Note on the TX filter bank: + * + * The TX path has 4 bands, which we call BAND0 through BAND3. + * For all frequencies, there are gain values where we bypass the filter + * bank. In this case, the band setting does not apply (does not have any + * meaning). + * + * The lowband, when not disabling the filter bank, always goes through + * BAND0, but there are non-lowband frequencies which can also go through + * BAND0. + * + * The following constants define lower cutoff frequencies for each band. + * BAND0 does not have a lower cutoff frequency, it is implied by + * MAGNESIUM_MIN_FREQ. MAGNESIUM_TX_BAND1_MIN_FREQ is the cutover frequency + * for switching from BAND0 to BAND1, and so on. + * + * On current Magnesium revisions, all filters on the TX filter bank are + * low pass filters (no high pass filters). + * Frequencies need to be chosen to allow as much of the full bandwidth + * through unattenuated (so don't go all the way up to the cutoff frequency + * of that filter, OK). + */ +constexpr double MAGNESIUM_TX_BAND1_MIN_FREQ = 723.17e6; +constexpr double MAGNESIUM_TX_BAND2_MIN_FREQ = 1623.17e6; +constexpr double MAGNESIUM_TX_BAND3_MIN_FREQ = 3323.17e6; +} // namespace -magnesium_radio_ctrl_impl::rx_band -magnesium_radio_ctrl_impl::_map_freq_to_rx_band(const double freq) { +magnesium_radio_ctrl_impl::rx_band magnesium_radio_ctrl_impl::_map_freq_to_rx_band( + const double freq) +{ magnesium_radio_ctrl_impl::rx_band band; if (fp_compare_epsilon<double>(freq) < MAGNESIUM_MIN_FREQ) { @@ -130,8 +131,9 @@ magnesium_radio_ctrl_impl::_map_freq_to_rx_band(const double freq) { return band; } -magnesium_radio_ctrl_impl::tx_band -magnesium_radio_ctrl_impl::_map_freq_to_tx_band(const double freq) { +magnesium_radio_ctrl_impl::tx_band magnesium_radio_ctrl_impl::_map_freq_to_tx_band( + const double freq) +{ magnesium_radio_ctrl_impl::tx_band band; if (fp_compare_epsilon<double>(freq) < MAGNESIUM_MIN_FREQ) { @@ -152,4 +154,3 @@ magnesium_radio_ctrl_impl::_map_freq_to_tx_band(const double freq) { return band; } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp index e19603b94..a045d0558 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp @@ -7,17 +7,17 @@ #ifndef INCLUDED_LIBUHD_MAGNESIUM_CONSTANTS_HPP #define INCLUDED_LIBUHD_MAGNESIUM_CONSTANTS_HPP -#include <vector> -#include <string> -#include <cstddef> #include <uhd/types/ranges.hpp> +#include <cstddef> +#include <string> +#include <vector> -static constexpr size_t FPGPIO_MASTER_RADIO = 0; -static constexpr size_t TOTAL_RADIO_PORTS = 4; -static constexpr double AD9371_RX_MIN_BANDWIDTH = 20.0e6; // HZ +static constexpr size_t FPGPIO_MASTER_RADIO = 0; +static constexpr size_t TOTAL_RADIO_PORTS = 4; +static constexpr double AD9371_RX_MIN_BANDWIDTH = 20.0e6; // HZ static constexpr double AD9371_RX_MAX_BANDWIDTH = 100.0e6; // HZ -static constexpr double AD9371_TX_MIN_BANDWIDTH = 20.0e6; // HZ +static constexpr double AD9371_TX_MIN_BANDWIDTH = 20.0e6; // HZ static constexpr double AD9371_TX_MAX_BANDWIDTH = 100.0e6; // HZ static constexpr double AD9371_MIN_FREQ = 300.0e6; // Hz @@ -27,36 +27,36 @@ static constexpr double ADF4351_MIN_FREQ = 35.0e6; static constexpr double ADF4351_MAX_FREQ = 4.4e9; static const std::vector<double> MAGNESIUM_RADIO_RATES = {122.88e6, 125e6, 153.6e6}; -static constexpr double MAGNESIUM_RADIO_RATE = 125e6; // Hz -static constexpr double MAGNESIUM_MIN_FREQ = 1e6; // Hz -static constexpr double MAGNESIUM_MAX_FREQ = 6e9; // Hz +static constexpr double MAGNESIUM_RADIO_RATE = 125e6; // Hz +static constexpr double MAGNESIUM_MIN_FREQ = 1e6; // Hz +static constexpr double MAGNESIUM_MAX_FREQ = 6e9; // Hz static constexpr double MAGNESIUM_LOWBAND_FREQ = 300e6; -static constexpr double AD9371_MIN_RX_GAIN = 0.0; // dB -static constexpr double AD9371_MAX_RX_GAIN = 30.0; // dB +static constexpr double AD9371_MIN_RX_GAIN = 0.0; // dB +static constexpr double AD9371_MAX_RX_GAIN = 30.0; // dB static constexpr double AD9371_RX_GAIN_STEP = 0.5; -static constexpr double DSA_MIN_GAIN = 0; // dB -static constexpr double DSA_MAX_GAIN = 31.5; // dB -static constexpr double DSA_GAIN_STEP = 0.5; // db -static constexpr double AMP_MIN_GAIN = 0; // dB -static constexpr double AMP_MAX_GAIN = 10; // dB -static constexpr double AMP_GAIN_STEP = 10;// dB -static constexpr double AD9371_MIN_TX_GAIN = 0.0; // dB -static constexpr double AD9371_MAX_TX_GAIN = 41.95; // dB +static constexpr double DSA_MIN_GAIN = 0; // dB +static constexpr double DSA_MAX_GAIN = 31.5; // dB +static constexpr double DSA_GAIN_STEP = 0.5; // db +static constexpr double AMP_MIN_GAIN = 0; // dB +static constexpr double AMP_MAX_GAIN = 10; // dB +static constexpr double AMP_GAIN_STEP = 10; // dB +static constexpr double AD9371_MIN_TX_GAIN = 0.0; // dB +static constexpr double AD9371_MAX_TX_GAIN = 41.95; // dB static constexpr double AD9371_TX_GAIN_STEP = 0.05; -static constexpr double ALL_RX_MIN_GAIN = 0.0; -static constexpr double ALL_RX_MAX_GAIN = 75.0; -static constexpr double ALL_RX_GAIN_STEP = 0.5; -static constexpr double ALL_TX_MIN_GAIN = 0.0; -static constexpr double ALL_TX_MAX_GAIN = 65.0; -static constexpr double ALL_TX_GAIN_STEP = 0.5; +static constexpr double ALL_RX_MIN_GAIN = 0.0; +static constexpr double ALL_RX_MAX_GAIN = 75.0; +static constexpr double ALL_RX_GAIN_STEP = 0.5; +static constexpr double ALL_TX_MIN_GAIN = 0.0; +static constexpr double ALL_TX_MAX_GAIN = 65.0; +static constexpr double ALL_TX_GAIN_STEP = 0.5; -static const uhd::freq_range_t MAGNESIUM_FREQ_RANGE(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ); +static const uhd::freq_range_t MAGNESIUM_FREQ_RANGE( + MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ); static const std::vector<std::string> MAGNESIUM_RX_ANTENNAS = { - "TX/RX", "RX2", "CAL", "LOCAL" -}; + "TX/RX", "RX2", "CAL", "LOCAL"}; //! AD9371 LO (for direct conversion) static constexpr char MAGNESIUM_LO1[] = "rfic"; @@ -72,7 +72,7 @@ static constexpr char MAGNESIUM_AMP[] = "amp"; // Note: MAGNESIUM_NUM_CHANS is independent of the number of chans per // RFNoC block. TODO: When we go to one radio per dboard, this comment can // be deleted. -static constexpr size_t MAGNESIUM_NUM_CHANS = 2; +static constexpr size_t MAGNESIUM_NUM_CHANS = 2; static constexpr double MAGNESIUM_RX_IF_FREQ = 2.44e9; static constexpr double MAGNESIUM_TX_IF_FREQ = 1.95e9; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.cpp index 3e68e2011..172f26390 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.cpp @@ -11,35 +11,26 @@ #include <chrono> namespace { - //! Address of the CPLD scratch register - const uint8_t CPLD_REGS_SCRATCH = 0x0040; +//! Address of the CPLD scratch register +const uint8_t CPLD_REGS_SCRATCH = 0x0040; - //! Address of the CPLD reset register - const uint8_t CPLD_REGS_RESET = 0x0041; -} +//! Address of the CPLD reset register +const uint8_t CPLD_REGS_RESET = 0x0041; +} // namespace -magnesium_cpld_ctrl::magnesium_cpld_ctrl( - write_spi_t write_fn, - read_spi_t read_fn -) +magnesium_cpld_ctrl::magnesium_cpld_ctrl(write_spi_t write_fn, read_spi_t read_fn) { - _write_fn = [write_fn](const uint8_t addr, const uint32_t data){ + _write_fn = [write_fn](const uint8_t addr, const uint32_t data) { UHD_LOG_TRACE("MG_CPLD", - str(boost::format("Writing to CPLD: 0x%02X -> 0x%04X") - % uint32_t(addr) % data)); - const uint32_t spi_transaction = 0 - | ((addr & 0x7F) << 16) - | data - ; + str(boost::format("Writing to CPLD: 0x%02X -> 0x%04X") % uint32_t(addr) + % data)); + const uint32_t spi_transaction = 0 | ((addr & 0x7F) << 16) | data; write_fn(spi_transaction); }; - _read_fn = [read_fn](const uint8_t addr){ + _read_fn = [read_fn](const uint8_t addr) { UHD_LOG_TRACE("MG_CPLD", - str(boost::format("Reading from CPLD address 0x%02X") - % uint32_t(addr))); - const uint32_t spi_transaction = (1<<23) - | ((addr & 0x7F) << 16) - ; + str(boost::format("Reading from CPLD address 0x%02X") % uint32_t(addr))); + const uint32_t spi_transaction = (1 << 23) | ((addr & 0x7F) << 16); return read_fn(spi_transaction); }; @@ -82,23 +73,24 @@ uint16_t magnesium_cpld_ctrl::get_scratch() return get_reg(CPLD_REGS_SCRATCH); } -void magnesium_cpld_ctrl::set_tx_switches( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_tx_switches(const chan_sel_t chan, const tx_sw1_t tx_sw1, const tx_sw2_t tx_sw2, const tx_sw3_t tx_sw3, const lowband_mixer_path_sel_t select_lowband_mixer_path, const bool enb_lowband_mixer, const atr_state_t atr_state, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { _regs.ch1_idle_tx_sw1 = magnesium_cpld_regs_t::ch1_idle_tx_sw1_t(tx_sw1); _regs.ch1_idle_tx_sw2 = magnesium_cpld_regs_t::ch1_idle_tx_sw2_t(tx_sw2); _regs.ch1_idle_tx_sw3 = magnesium_cpld_regs_t::ch1_idle_tx_sw3_t(tx_sw3); - _regs.ch1_idle_tx_lowband_mixer_path_select = magnesium_cpld_regs_t::ch1_idle_tx_lowband_mixer_path_select_t(select_lowband_mixer_path); + _regs.ch1_idle_tx_lowband_mixer_path_select = + magnesium_cpld_regs_t::ch1_idle_tx_lowband_mixer_path_select_t( + select_lowband_mixer_path); _regs.ch1_idle_tx_mixer_en = enb_lowband_mixer; } if (atr_state == ON or atr_state == ANY) { @@ -106,7 +98,8 @@ void magnesium_cpld_ctrl::set_tx_switches( _regs.ch1_on_tx_sw2 = magnesium_cpld_regs_t::ch1_on_tx_sw2_t(tx_sw2); _regs.ch1_on_tx_sw3 = magnesium_cpld_regs_t::ch1_on_tx_sw3_t(tx_sw3); _regs.ch1_on_tx_lowband_mixer_path_select = - magnesium_cpld_regs_t::ch1_on_tx_lowband_mixer_path_select_t(select_lowband_mixer_path); + magnesium_cpld_regs_t::ch1_on_tx_lowband_mixer_path_select_t( + select_lowband_mixer_path); _regs.ch1_on_tx_mixer_en = enb_lowband_mixer; } } @@ -116,7 +109,8 @@ void magnesium_cpld_ctrl::set_tx_switches( _regs.ch2_idle_tx_sw2 = magnesium_cpld_regs_t::ch2_idle_tx_sw2_t(tx_sw1); _regs.ch2_idle_tx_sw3 = magnesium_cpld_regs_t::ch2_idle_tx_sw3_t(tx_sw1); _regs.ch2_idle_tx_lowband_mixer_path_select = - magnesium_cpld_regs_t::ch2_idle_tx_lowband_mixer_path_select_t(select_lowband_mixer_path); + magnesium_cpld_regs_t::ch2_idle_tx_lowband_mixer_path_select_t( + select_lowband_mixer_path); _regs.ch2_idle_tx_mixer_en = enb_lowband_mixer; } if (atr_state == ON or atr_state == ANY) { @@ -124,7 +118,8 @@ void magnesium_cpld_ctrl::set_tx_switches( _regs.ch2_on_tx_sw2 = magnesium_cpld_regs_t::ch2_on_tx_sw2_t(tx_sw2); _regs.ch2_on_tx_sw3 = magnesium_cpld_regs_t::ch2_on_tx_sw3_t(tx_sw3); _regs.ch2_on_tx_lowband_mixer_path_select = - magnesium_cpld_regs_t::ch2_on_tx_lowband_mixer_path_select_t(select_lowband_mixer_path); + magnesium_cpld_regs_t::ch2_on_tx_lowband_mixer_path_select_t( + select_lowband_mixer_path); _regs.ch2_on_tx_mixer_en = enb_lowband_mixer; } } @@ -134,8 +129,7 @@ void magnesium_cpld_ctrl::set_tx_switches( } } -void magnesium_cpld_ctrl::set_rx_switches( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_rx_switches(const chan_sel_t chan, const rx_sw2_t rx_sw2, const rx_sw3_t rx_sw3, const rx_sw4_t rx_sw4, @@ -144,8 +138,8 @@ void magnesium_cpld_ctrl::set_rx_switches( const lowband_mixer_path_sel_t select_lowband_mixer_path, const bool enb_lowband_mixer, const atr_state_t atr_state, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { @@ -154,7 +148,9 @@ void magnesium_cpld_ctrl::set_rx_switches( _regs.ch1_idle_rx_sw4 = magnesium_cpld_regs_t::ch1_idle_rx_sw4_t(rx_sw4); _regs.ch1_idle_rx_sw5 = magnesium_cpld_regs_t::ch1_idle_rx_sw5_t(rx_sw5); _regs.ch1_idle_rx_sw6 = magnesium_cpld_regs_t::ch1_idle_rx_sw6_t(rx_sw6); - _regs.ch1_idle_rx_loband_mixer_path_sel = magnesium_cpld_regs_t::ch1_idle_rx_loband_mixer_path_sel_t(select_lowband_mixer_path); + _regs.ch1_idle_rx_loband_mixer_path_sel = + magnesium_cpld_regs_t::ch1_idle_rx_loband_mixer_path_sel_t( + select_lowband_mixer_path); _regs.ch1_idle_rx_mixer_en = enb_lowband_mixer; } if (atr_state == ON or atr_state == ANY) { @@ -163,7 +159,9 @@ void magnesium_cpld_ctrl::set_rx_switches( _regs.ch1_on_rx_sw4 = magnesium_cpld_regs_t::ch1_on_rx_sw4_t(rx_sw4); _regs.ch1_on_rx_sw5 = magnesium_cpld_regs_t::ch1_on_rx_sw5_t(rx_sw5); _regs.ch1_on_rx_sw6 = magnesium_cpld_regs_t::ch1_on_rx_sw6_t(rx_sw6); - _regs.ch1_on_rx_loband_mixer_path_sel = magnesium_cpld_regs_t::ch1_on_rx_loband_mixer_path_sel_t(select_lowband_mixer_path); + _regs.ch1_on_rx_loband_mixer_path_sel = + magnesium_cpld_regs_t::ch1_on_rx_loband_mixer_path_sel_t( + select_lowband_mixer_path); _regs.ch1_on_rx_mixer_en = enb_lowband_mixer; } } @@ -175,7 +173,8 @@ void magnesium_cpld_ctrl::set_rx_switches( _regs.ch2_idle_rx_sw5 = magnesium_cpld_regs_t::ch2_idle_rx_sw5_t(rx_sw5); _regs.ch2_idle_rx_sw6 = magnesium_cpld_regs_t::ch2_idle_rx_sw6_t(rx_sw6); _regs.ch2_idle_rx_loband_mixer_path_sel = - magnesium_cpld_regs_t::ch2_idle_rx_loband_mixer_path_sel_t(select_lowband_mixer_path); + magnesium_cpld_regs_t::ch2_idle_rx_loband_mixer_path_sel_t( + select_lowband_mixer_path); _regs.ch2_idle_rx_mixer_en = enb_lowband_mixer; } if (atr_state == ON or atr_state == ANY) { @@ -184,7 +183,9 @@ void magnesium_cpld_ctrl::set_rx_switches( _regs.ch2_on_rx_sw4 = magnesium_cpld_regs_t::ch2_on_rx_sw4_t(rx_sw4); _regs.ch2_on_rx_sw5 = magnesium_cpld_regs_t::ch2_on_rx_sw5_t(rx_sw5); _regs.ch2_on_rx_sw6 = magnesium_cpld_regs_t::ch2_on_rx_sw6_t(rx_sw6); - _regs.ch2_on_rx_loband_mixer_path_sel = magnesium_cpld_regs_t::ch2_on_rx_loband_mixer_path_sel_t(select_lowband_mixer_path); + _regs.ch2_on_rx_loband_mixer_path_sel = + magnesium_cpld_regs_t::ch2_on_rx_loband_mixer_path_sel_t( + select_lowband_mixer_path); _regs.ch2_on_rx_mixer_en = enb_lowband_mixer; } } @@ -193,40 +194,39 @@ void magnesium_cpld_ctrl::set_rx_switches( } } -void magnesium_cpld_ctrl::set_tx_atr_bits( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_tx_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const bool tx_led, const bool tx_pa_enb, const bool tx_amp_enb, const bool tx_myk_en, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { - _regs.ch1_idle_tx_led = tx_led; - _regs.ch1_idle_tx_pa_en = tx_pa_enb; + _regs.ch1_idle_tx_led = tx_led; + _regs.ch1_idle_tx_pa_en = tx_pa_enb; _regs.ch1_idle_tx_amp_en = tx_amp_enb; _regs.ch1_idle_tx_myk_en = tx_myk_en; } if (atr_state == ON or atr_state == ANY) { - _regs.ch1_on_tx_led = tx_led; - _regs.ch1_on_tx_pa_en = tx_pa_enb; + _regs.ch1_on_tx_led = tx_led; + _regs.ch1_on_tx_pa_en = tx_pa_enb; _regs.ch1_on_tx_amp_en = tx_amp_enb; _regs.ch1_on_tx_myk_en = tx_myk_en; } } if (chan == CHAN2 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { - _regs.ch2_idle_tx_led = tx_led; - _regs.ch2_idle_tx_pa_en = tx_pa_enb; + _regs.ch2_idle_tx_led = tx_led; + _regs.ch2_idle_tx_pa_en = tx_pa_enb; _regs.ch2_idle_tx_amp_en = tx_amp_enb; _regs.ch2_idle_tx_myk_en = tx_myk_en; } if (atr_state == ON or atr_state == ANY) { - _regs.ch2_on_tx_led = tx_led; - _regs.ch2_on_tx_pa_en = tx_pa_enb; + _regs.ch2_on_tx_led = tx_led; + _regs.ch2_on_tx_pa_en = tx_pa_enb; _regs.ch2_on_tx_amp_en = tx_amp_enb; _regs.ch2_on_tx_myk_en = tx_myk_en; } @@ -236,31 +236,26 @@ void magnesium_cpld_ctrl::set_tx_atr_bits( } } -void magnesium_cpld_ctrl::set_trx_sw_atr_bits( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_trx_sw_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const sw_trx_t trx_sw, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { - _regs.ch1_idle_sw_trx = - magnesium_cpld_regs_t::ch1_idle_sw_trx_t(trx_sw); + _regs.ch1_idle_sw_trx = magnesium_cpld_regs_t::ch1_idle_sw_trx_t(trx_sw); } if (atr_state == ON or atr_state == ANY) { - _regs.ch1_on_sw_trx = - magnesium_cpld_regs_t::ch1_on_sw_trx_t(trx_sw); + _regs.ch1_on_sw_trx = magnesium_cpld_regs_t::ch1_on_sw_trx_t(trx_sw); } } if (chan == CHAN2 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { - _regs.ch2_idle_sw_trx = - magnesium_cpld_regs_t::ch2_idle_sw_trx_t(trx_sw); + _regs.ch2_idle_sw_trx = magnesium_cpld_regs_t::ch2_idle_sw_trx_t(trx_sw); } if (atr_state == ON or atr_state == ANY) { - _regs.ch2_on_sw_trx = - magnesium_cpld_regs_t::ch2_on_sw_trx_t(trx_sw); + _regs.ch2_on_sw_trx = magnesium_cpld_regs_t::ch2_on_sw_trx_t(trx_sw); } } if (not defer_commit) { @@ -268,40 +263,35 @@ void magnesium_cpld_ctrl::set_trx_sw_atr_bits( } } -void magnesium_cpld_ctrl::set_rx_input_atr_bits( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_rx_input_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const rx_sw1_t rx_sw1, const bool rx_led, const bool rx2_led, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { - _regs.ch1_idle_rx_sw1 = - magnesium_cpld_regs_t::ch1_idle_rx_sw1_t(rx_sw1); - _regs.ch1_idle_rx_led = rx_led; + _regs.ch1_idle_rx_sw1 = magnesium_cpld_regs_t::ch1_idle_rx_sw1_t(rx_sw1); + _regs.ch1_idle_rx_led = rx_led; _regs.ch1_idle_rx2_led = rx2_led; } if (atr_state == ON or atr_state == ANY) { - _regs.ch1_on_rx_sw1 = - magnesium_cpld_regs_t::ch1_on_rx_sw1_t(rx_sw1); - _regs.ch1_on_rx_led = rx_led; + _regs.ch1_on_rx_sw1 = magnesium_cpld_regs_t::ch1_on_rx_sw1_t(rx_sw1); + _regs.ch1_on_rx_led = rx_led; _regs.ch1_on_rx2_led = rx2_led; } } if (chan == CHAN2 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { - _regs.ch2_idle_rx_sw1 = - magnesium_cpld_regs_t::ch2_idle_rx_sw1_t(rx_sw1); - _regs.ch2_idle_rx_led = rx_led; + _regs.ch2_idle_rx_sw1 = magnesium_cpld_regs_t::ch2_idle_rx_sw1_t(rx_sw1); + _regs.ch2_idle_rx_led = rx_led; _regs.ch2_idle_rx2_led = rx2_led; } if (atr_state == ON or atr_state == ANY) { - _regs.ch2_on_rx_sw1 = - magnesium_cpld_regs_t::ch2_on_rx_sw1_t(rx_sw1); - _regs.ch2_on_rx_led = rx_led; + _regs.ch2_on_rx_sw1 = magnesium_cpld_regs_t::ch2_on_rx_sw1_t(rx_sw1); + _regs.ch2_on_rx_led = rx_led; _regs.ch2_on_rx2_led = rx2_led; } } @@ -311,13 +301,12 @@ void magnesium_cpld_ctrl::set_rx_input_atr_bits( } } -void magnesium_cpld_ctrl::set_rx_atr_bits( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_rx_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const bool rx_amp_enb, const bool rx_myk_en, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { @@ -345,13 +334,12 @@ void magnesium_cpld_ctrl::set_rx_atr_bits( } } -void magnesium_cpld_ctrl::set_rx_lna_atr_bits( - const chan_sel_t chan, +void magnesium_cpld_ctrl::set_rx_lna_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const bool rx_lna1_enb, const bool rx_lna2_enb, - const bool defer_commit -) { + const bool defer_commit) +{ std::lock_guard<std::mutex> l(_set_mutex); if (chan == CHAN1 or chan == BOTH) { if (atr_state == IDLE or atr_state == ANY) { @@ -394,9 +382,7 @@ void magnesium_cpld_ctrl::_loopback_test() if (actual != random_number) { UHD_LOGGER_ERROR("MG_CPLD") << "CPLD scratch loopback failed! " - << boost::format("Expected: 0x%04X Got: 0x%04X") - % random_number % actual - ; + << boost::format("Expected: 0x%04X Got: 0x%04X") % random_number % actual; throw uhd::runtime_error("CPLD scratch loopback failed!"); } UHD_LOG_TRACE("MG_CPLD", "CPLD scratch loopback test passed!"); @@ -406,19 +392,16 @@ void magnesium_cpld_ctrl::_loopback_test() void magnesium_cpld_ctrl::commit(const bool save_all) { UHD_LOGGER_TRACE("MG_CPLD") - << "Storing register cache " - << (save_all ? "completely" : "selectively") - << " to CPLD via SPI..." - ; - auto changed_addrs = save_all ? - _regs.get_all_addrs() : - _regs.get_changed_addrs<size_t>(); - for (const auto addr: changed_addrs) { + << "Storing register cache " << (save_all ? "completely" : "selectively") + << " to CPLD via SPI..."; + auto changed_addrs = save_all ? _regs.get_all_addrs() + : _regs.get_changed_addrs<size_t>(); + for (const auto addr : changed_addrs) { _write_fn(addr, _regs.get_reg(addr)); } _regs.save_state(); UHD_LOG_TRACE("MG_CPLD", - "Storing cache complete: " \ - "Updated " << changed_addrs.size() << " registers."); + "Storing cache complete: " + "Updated " + << changed_addrs.size() << " registers."); } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp index fc3af77de..05455e3fd 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp @@ -8,10 +8,10 @@ #define INCLUDED_LIBUHD_MAGNESIUM_CPLD_CTRL_HPP #include "adf4351_regs.hpp" -#include <uhd/types/serial.hpp> #include "magnesium_cpld_regs.hpp" -#include <mutex> +#include <uhd/types/serial.hpp> #include <memory> +#include <mutex> //! Controls the CPLD on a Magnesium daughterboard // @@ -31,21 +31,13 @@ public: //! ATR state: The CPLD has 2 states for RX and TX each, not like the radio // which has 4 states (one for every RX/TX state combo). - enum atr_state_t { - IDLE, - ON, - ANY - }; + enum atr_state_t { IDLE, ON, ANY }; //! Channel select: One CPLD controls both channels on a daughterboard - enum chan_sel_t { - CHAN1, - CHAN2, - BOTH - }; + enum chan_sel_t { CHAN1, CHAN2, BOTH }; enum tx_sw1_t { - TX_SW1_SHUTDOWNTXSW1 = 0, + TX_SW1_SHUTDOWNTXSW1 = 0, TX_SW1_FROMTXFILTERLP1700MHZ = 1, TX_SW1_FROMTXFILTERLP3400MHZ = 2, TX_SW1_FROMTXFILTERLP0800MHZ = 3 @@ -58,59 +50,56 @@ public: TX_SW2_TOTXFILTERLP6400MHZ = 8 }; - enum tx_sw3_t { - TX_SW3_TOTXFILTERBANKS = 0, - TX_SW3_BYPASSPATHTOTRXSW = 1 - }; + enum tx_sw3_t { TX_SW3_TOTXFILTERBANKS = 0, TX_SW3_BYPASSPATHTOTRXSW = 1 }; enum sw_trx_t { - SW_TRX_FROMLOWERFILTERBANKTXSW1 = 0, + SW_TRX_FROMLOWERFILTERBANKTXSW1 = 0, SW_TRX_FROMTXUPPERFILTERBANKLP6400MHZ = 1, - SW_TRX_RXCHANNELPATH = 2, - SW_TRX_BYPASSPATHTOTXSW3 = 3 + SW_TRX_RXCHANNELPATH = 2, + SW_TRX_BYPASSPATHTOTXSW3 = 3 }; enum rx_sw1_t { - RX_SW1_TXRXINPUT = 0, - RX_SW1_RXLOCALINPUT = 1, + RX_SW1_TXRXINPUT = 0, + RX_SW1_RXLOCALINPUT = 1, RX_SW1_TRXSWITCHOUTPUT = 2, - RX_SW1_RX2INPUT = 3 + RX_SW1_RX2INPUT = 3 }; enum rx_sw2_t { - RX_SW2_SHUTDOWNSW2 = 0, + RX_SW2_SHUTDOWNSW2 = 0, RX_SW2_LOWERFILTERBANKTOSWITCH3 = 1, - RX_SW2_BYPASSPATHTOSWITCH6 = 2, + RX_SW2_BYPASSPATHTOSWITCH6 = 2, RX_SW2_UPPERFILTERBANKTOSWITCH4 = 3 }; enum rx_sw3_t { RX_SW3_FILTER2100X2850MHZ = 0, - RX_SW3_FILTER0490LPMHZ = 1, + RX_SW3_FILTER0490LPMHZ = 1, RX_SW3_FILTER1600X2250MHZ = 2, RX_SW3_FILTER0440X0530MHZ = 4, RX_SW3_FILTER0650X1000MHZ = 5, RX_SW3_FILTER1100X1575MHZ = 6, - RX_SW3_SHUTDOWNSW3 = 7 + RX_SW3_SHUTDOWNSW3 = 7 }; enum rx_sw4_t { RX_SW4_FILTER2100X2850MHZFROM = 1, RX_SW4_FILTER1600X2250MHZFROM = 2, - RX_SW4_FILTER2700HPMHZ = 4 + RX_SW4_FILTER2700HPMHZ = 4 }; enum rx_sw5_t { RX_SW5_FILTER0440X0530MHZFROM = 1, RX_SW5_FILTER1100X1575MHZFROM = 2, - RX_SW5_FILTER0490LPMHZFROM = 4, + RX_SW5_FILTER0490LPMHZFROM = 4, RX_SW5_FILTER0650X1000MHZFROM = 8 }; enum rx_sw6_t { RX_SW6_LOWERFILTERBANKFROMSWITCH5 = 1, RX_SW6_UPPERFILTERBANKFROMSWITCH4 = 2, - RX_SW6_BYPASSPATHFROMSWITCH2 = 4 + RX_SW6_BYPASSPATHFROMSWITCH2 = 4 }; enum lowband_mixer_path_sel_t { @@ -124,10 +113,7 @@ public: * \param write_spi_fn SPI write functor * \param read_spi_fn SPI read functor */ - magnesium_cpld_ctrl( - write_spi_t write_spi_fn, - read_spi_t read_spi_fn - ); + magnesium_cpld_ctrl(write_spi_t write_spi_fn, read_spi_t read_spi_fn); /************************************************************************** * API @@ -167,16 +153,14 @@ public: * \param atr_state If IDLE, only update the idle register. If ON, only * enable the on register. If ANY, update both. */ - void set_tx_switches( - const chan_sel_t chan, + void set_tx_switches(const chan_sel_t chan, const tx_sw1_t tx_sw1, const tx_sw2_t tx_sw2, const tx_sw3_t tx_sw3, const lowband_mixer_path_sel_t select_lowband_mixer_path, const bool enb_lowband_mixer, const atr_state_t atr_state = ANY, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! Frequency-related settings, receive side * @@ -194,8 +178,7 @@ public: * \param atr_state If IDLE, only update the idle register. If ON, only * enable the on register. If ANY, update both. */ - void set_rx_switches( - const chan_sel_t chan, + void set_rx_switches(const chan_sel_t chan, const rx_sw2_t rx_sw2, const rx_sw3_t rx_sw3, const rx_sw4_t rx_sw4, @@ -204,8 +187,7 @@ public: const lowband_mixer_path_sel_t select_lowband_mixer_path, const bool enb_lowband_mixer, const atr_state_t atr_state = ANY, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! ATR settings: LEDs, PAs, LNAs, ... for TX side * @@ -223,15 +205,13 @@ public: * \param tx_amp_enb State of the TX amp for this ATR state (on or off) * \param tx_myk_enb State of the AD9371 TX enable pin for this ATR state */ - void set_tx_atr_bits( - const chan_sel_t chan, + void set_tx_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const bool tx_led, const bool tx_pa_enb, const bool tx_amp_enb, const bool tx_myk_enb, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! ATR settings: TRX switch * @@ -242,12 +222,10 @@ public: * \param atr_state TX state for which these settings apply. * \param trx_sw State of the TRX switch for this ATR state */ - void set_trx_sw_atr_bits( - const chan_sel_t chan, + void set_trx_sw_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const sw_trx_t trx_sw, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! ATR settings: LEDs, input switches for RX side * @@ -263,14 +241,12 @@ public: * \param rx2_led State of the RX LED for this ATR state (on or off). This * is the LED on the RX2 port. */ - void set_rx_input_atr_bits( - const chan_sel_t chan, + void set_rx_input_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const rx_sw1_t rx_sw1, const bool rx_led, const bool rx2_led, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! ATR settings: Amp, Mykonos settings for RX side * @@ -287,13 +263,11 @@ public: * \param rx_amp_enb State of RX amp for this ATR state (on or off). * \param rx_myk_enb State of the AD9371 RX enable pin for this ATR state */ - void set_rx_atr_bits( - const chan_sel_t chan, + void set_rx_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const bool rx_amp_enb, const bool rx_myk_en, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! ATR settings: LNAs for RX side * @@ -311,13 +285,11 @@ public: * \param rx_lna2_enb State of RX LNA 2 for this ATR state (on or off). * This is the low-band LNA. */ - void set_rx_lna_atr_bits( - const chan_sel_t chan, + void set_rx_lna_atr_bits(const chan_sel_t chan, const atr_state_t atr_state, const bool rx_lna1_enb, const bool rx_lna2_enb, - const bool defer_commit = false - ); + const bool defer_commit = false); private: //! Write functor: Take address / data pair, craft SPI transaction diff --git a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp index 05b6dbe8f..67b20f5fa 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp @@ -15,47 +15,45 @@ using namespace uhd::rfnoc; using namespace magnesium; namespace { - typedef magnesium_radio_ctrl_impl::rx_band rx_band; - typedef magnesium_radio_ctrl_impl::tx_band tx_band; +typedef magnesium_radio_ctrl_impl::rx_band rx_band; +typedef magnesium_radio_ctrl_impl::tx_band tx_band; - const size_t TX_LOWBAND = 0; - const size_t TX_HIGHBAND = 1; - const size_t RX_LOWBAND = 0; - const size_t RX_MIDBAND = 1; - const size_t RX_HIGHBAND = 2; +const size_t TX_LOWBAND = 0; +const size_t TX_HIGHBAND = 1; +const size_t RX_LOWBAND = 0; +const size_t RX_MIDBAND = 1; +const size_t RX_HIGHBAND = 2; - size_t map_tx_band(const tx_band band) - { - if (band == tx_band::LOWBAND) { - return TX_LOWBAND; - } - return TX_HIGHBAND; +size_t map_tx_band(const tx_band band) +{ + if (band == tx_band::LOWBAND) { + return TX_LOWBAND; } + return TX_HIGHBAND; +} - size_t map_rx_band(const rx_band band) - { - if (band == rx_band::LOWBAND) { - return RX_LOWBAND; - } - if (band == rx_band::BAND0 or - band == rx_band::BAND1 or - band == rx_band::BAND2 or - band == rx_band::BAND3) { - return RX_MIDBAND; - } - return RX_HIGHBAND; +size_t map_rx_band(const rx_band band) +{ + if (band == rx_band::LOWBAND) { + return RX_LOWBAND; + } + if (band == rx_band::BAND0 or band == rx_band::BAND1 or band == rx_band::BAND2 + or band == rx_band::BAND3) { + return RX_MIDBAND; } + return RX_HIGHBAND; +} - //! Maps gain index -> gain_tuple_t - // - // Note: This is an int, for easier lookups. We're basically hardcoding the - // knowledge that the gain map has a 1 dB granularity. - using gain_tuple_map_t = std::map<int, gain_tuple_t>; +//! Maps gain index -> gain_tuple_t +// +// Note: This is an int, for easier lookups. We're basically hardcoding the +// knowledge that the gain map has a 1 dB granularity. +using gain_tuple_map_t = std::map<int, gain_tuple_t>; - //! Maps band -> gain_tuple_map_t - using gain_tables_t = std::map<size_t, gain_tuple_map_t>; +//! Maps band -> gain_tuple_map_t +using gain_tables_t = std::map<size_t, gain_tuple_map_t>; - // clang-format off +// clang-format off /*! RX gain tables */ const gain_tables_t rx_gain_tables = { @@ -437,53 +435,38 @@ namespace { {65, {0, 0, false}} }} }; /* tx_gain_tables */ - // clang-format on +// clang-format on - gain_tuple_t fine_tune_ad9371_att( - const gain_tuple_t gain_tuple, - const double gain_index - ) { - // Here, we hardcode the half-dB steps. We soak up all half-dB - // steps by twiddling the AD9371 attenuation, but we need to make - // sure we don't make it negative. - if (gain_index - int(gain_index) >= .5) { - gain_tuple_t gt2 = gain_tuple; - gt2.ad9371_att = std::max(0.0, gain_tuple.ad9371_att - .5); - return gt2; - } - return gain_tuple; +gain_tuple_t fine_tune_ad9371_att(const gain_tuple_t gain_tuple, const double gain_index) +{ + // Here, we hardcode the half-dB steps. We soak up all half-dB + // steps by twiddling the AD9371 attenuation, but we need to make + // sure we don't make it negative. + if (gain_index - int(gain_index) >= .5) { + gain_tuple_t gt2 = gain_tuple; + gt2.ad9371_att = std::max(0.0, gain_tuple.ad9371_att - .5); + return gt2; } + return gain_tuple; +} -} /* namespace ANON */ +} // namespace gain_tuple_t magnesium::get_rx_gain_tuple( - const double gain_index, - const magnesium_radio_ctrl_impl::rx_band band -) { - UHD_ASSERT_THROW( - gain_index <= ALL_RX_MAX_GAIN and gain_index >= ALL_RX_MIN_GAIN - ); - auto &gain_table = rx_gain_tables.at(map_rx_band(band)); + const double gain_index, const magnesium_radio_ctrl_impl::rx_band band) +{ + UHD_ASSERT_THROW(gain_index <= ALL_RX_MAX_GAIN and gain_index >= ALL_RX_MIN_GAIN); + auto& gain_table = rx_gain_tables.at(map_rx_band(band)); const int gain_index_truncd = int(gain_index); - return fine_tune_ad9371_att( - gain_table.at(gain_index_truncd), - gain_index - ); + return fine_tune_ad9371_att(gain_table.at(gain_index_truncd), gain_index); } gain_tuple_t magnesium::get_tx_gain_tuple( - const double gain_index, - const magnesium_radio_ctrl_impl::tx_band band -) { - UHD_ASSERT_THROW( - gain_index <= ALL_TX_MAX_GAIN and gain_index >= ALL_TX_MIN_GAIN - ); - auto &gain_table = tx_gain_tables.at(map_tx_band(band)); + const double gain_index, const magnesium_radio_ctrl_impl::tx_band band) +{ + UHD_ASSERT_THROW(gain_index <= ALL_TX_MAX_GAIN and gain_index >= ALL_TX_MIN_GAIN); + auto& gain_table = tx_gain_tables.at(map_tx_band(band)); const int gain_index_truncd = int(gain_index); - return fine_tune_ad9371_att( - gain_table.at(gain_index_truncd), - gain_index - ); + return fine_tune_ad9371_att(gain_table.at(gain_index_truncd), gain_index); } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp index e36bdd59c..8769b44ac 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp @@ -31,16 +31,12 @@ struct gain_tuple_t /*! Given a gain index, return a tuple of gain-related settings (Rx) */ gain_tuple_t get_rx_gain_tuple( - const double gain_index, - const uhd::rfnoc::magnesium_radio_ctrl_impl::rx_band band_ -); + const double gain_index, const uhd::rfnoc::magnesium_radio_ctrl_impl::rx_band band_); /*! Given a gain index, return a tuple of gain-related settings (Tx) */ gain_tuple_t get_tx_gain_tuple( - const double gain_index, - const uhd::rfnoc::magnesium_radio_ctrl_impl::tx_band band_ -); + const double gain_index, const uhd::rfnoc::magnesium_radio_ctrl_impl::tx_band band_); } /* namespace magnesium */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp index 9ddb2cfcb..3c66a3b62 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp @@ -4,37 +4,32 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "magnesium_radio_ctrl_impl.hpp" -#include "magnesium_cpld_ctrl.hpp" #include "magnesium_constants.hpp" +#include "magnesium_cpld_ctrl.hpp" +#include "magnesium_radio_ctrl_impl.hpp" #include <uhd/utils/log.hpp> using namespace uhd; using namespace uhd::usrp; using namespace uhd::rfnoc; -void magnesium_radio_ctrl_impl::_identify_with_leds( - const int identify_duration -) { - auto end_time = std::chrono::steady_clock::now() - + std::chrono::seconds(identify_duration); +void magnesium_radio_ctrl_impl::_identify_with_leds(const int identify_duration) +{ + auto end_time = + std::chrono::steady_clock::now() + std::chrono::seconds(identify_duration); bool led_state = true; while (std::chrono::steady_clock::now() < end_time) { - _cpld->set_tx_atr_bits( - magnesium_cpld_ctrl::BOTH, + _cpld->set_tx_atr_bits(magnesium_cpld_ctrl::BOTH, magnesium_cpld_ctrl::ANY, led_state, false, false, - true - ); - _cpld->set_rx_input_atr_bits( - magnesium_cpld_ctrl::BOTH, + true); + _cpld->set_rx_input_atr_bits(magnesium_cpld_ctrl::BOTH, magnesium_cpld_ctrl::ANY, magnesium_cpld_ctrl::RX_SW1_TXRXINPUT, /* whatever */ led_state, - led_state - ); + led_state); led_state = !led_state; std::this_thread::sleep_for(std::chrono::milliseconds(500)); } @@ -44,27 +39,26 @@ void magnesium_radio_ctrl_impl::_identify_with_leds( void magnesium_radio_ctrl_impl::_update_atr_switches( const magnesium_cpld_ctrl::chan_sel_t chan, const direction_t dir, - const std::string &ant -){ + const std::string& ant) +{ if (dir == RX_DIRECTION or dir == DX_DIRECTION) { // These default values work for RX2 bool trx_led = false; bool rx2_led = true; - auto rx_sw1 = magnesium_cpld_ctrl::RX_SW1_RX2INPUT; + auto rx_sw1 = magnesium_cpld_ctrl::RX_SW1_RX2INPUT; // The TRX switch in TX-idle mode defaults to TX-on mode. When TX is // off, and we're receiving on TX/RX however, we need to point TRX to // RX SW1. In all other cases, a TX state toggle (on to idle or vice // versa) won't trigger a change of the TRX switch. auto sw_trx = _sw_trx[chan]; - UHD_LOG_TRACE(unique_id(), - "Updating all RX-ATR related switches for antenna==" << ant); + UHD_LOG_TRACE( + unique_id(), "Updating all RX-ATR related switches for antenna==" << ant); if (ant == "TX/RX") { - rx_sw1 = magnesium_cpld_ctrl::RX_SW1_TRXSWITCHOUTPUT; - sw_trx = magnesium_cpld_ctrl::SW_TRX_RXCHANNELPATH; + rx_sw1 = magnesium_cpld_ctrl::RX_SW1_TRXSWITCHOUTPUT; + sw_trx = magnesium_cpld_ctrl::SW_TRX_RXCHANNELPATH; trx_led = true; rx2_led = false; - } - else if (ant == "CAL") { + } else if (ant == "CAL") { // It makes intuitive sense to illuminate the green TX/RX LED when // receiving on CAL (because it goes over to the TX/RX port), but // the problem is that CAL is only useful when we're both TXing and @@ -72,35 +66,30 @@ void magnesium_radio_ctrl_impl::_update_atr_switches( // So, for CAL, we light up the green RX2 LED. trx_led = false; rx2_led = true; - rx_sw1 = magnesium_cpld_ctrl::RX_SW1_TXRXINPUT; - } - else if (ant == "LOCAL") { + rx_sw1 = magnesium_cpld_ctrl::RX_SW1_TXRXINPUT; + } else if (ant == "LOCAL") { rx_sw1 = magnesium_cpld_ctrl::RX_SW1_RXLOCALINPUT; } - _cpld->set_rx_input_atr_bits( - chan, + _cpld->set_rx_input_atr_bits(chan, magnesium_cpld_ctrl::ON, rx_sw1, trx_led, rx2_led, true /* defer commit */ ); - _cpld->set_rx_atr_bits( - chan, + _cpld->set_rx_atr_bits(chan, magnesium_cpld_ctrl::ON, - true, /* amp on */ - true, /* mykonos on */ - true /* defer commit */ + true, /* amp on */ + true, /* mykonos on */ + true /* defer commit */ ); - _cpld->set_rx_atr_bits( - chan, + _cpld->set_rx_atr_bits(chan, magnesium_cpld_ctrl::IDLE, - true, /* amp stays on */ - true, /* mykonos on */ - true /* defer commit */ + true, /* amp stays on */ + true, /* mykonos on */ + true /* defer commit */ ); - _cpld->set_trx_sw_atr_bits( - chan, + _cpld->set_trx_sw_atr_bits(chan, magnesium_cpld_ctrl::IDLE, /* idle here means TX is off */ sw_trx, false /* don't defer commit */ @@ -108,220 +97,203 @@ void magnesium_radio_ctrl_impl::_update_atr_switches( } if (dir == TX_DIRECTION or dir == DX_DIRECTION) { UHD_LOG_TRACE(unique_id(), "Updating all TX-ATR related switches..."); - _cpld->set_tx_atr_bits( - chan, + _cpld->set_tx_atr_bits(chan, magnesium_cpld_ctrl::ON, true, /* LED on */ true, /* PA on */ true, /* AMP on */ true, /* Myk on */ - true /* defer commit */ + true /* defer commit */ ); // Leaving PA on since we want shorter tx settling time. - _cpld->set_tx_atr_bits( - chan, + _cpld->set_tx_atr_bits(chan, magnesium_cpld_ctrl::IDLE, false, /* LED off */ true, /* PA on */ true, /* AMP on */ - true, /* Myk on */ - false /* don't defer commit */ + true, /* Myk on */ + false /* don't defer commit */ ); }; } -void magnesium_radio_ctrl_impl::_update_rx_freq_switches( - const double freq, +void magnesium_radio_ctrl_impl::_update_rx_freq_switches(const double freq, const bool bypass_lnas, - const magnesium_cpld_ctrl::chan_sel_t chan_sel -) { + const magnesium_cpld_ctrl::chan_sel_t chan_sel) +{ UHD_LOG_TRACE(unique_id(), - "Update all RX freq related switches. f=" << freq << " Hz, " - "bypass LNAS: " << (bypass_lnas ? "Yes" : "No") << ", chan=" << chan_sel - ); - auto rx_sw2 = magnesium_cpld_ctrl::RX_SW2_BYPASSPATHTOSWITCH6; - auto rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; - auto rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; - auto rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM; - auto rx_sw6 = magnesium_cpld_ctrl::RX_SW6_BYPASSPATHFROMSWITCH2; - const auto band = _map_freq_to_rx_band(freq); + "Update all RX freq related switches. f=" << freq + << " Hz, " + "bypass LNAS: " + << (bypass_lnas ? "Yes" : "No") + << ", chan=" << chan_sel); + auto rx_sw2 = magnesium_cpld_ctrl::RX_SW2_BYPASSPATHTOSWITCH6; + auto rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; + auto rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; + auto rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM; + auto rx_sw6 = magnesium_cpld_ctrl::RX_SW6_BYPASSPATHFROMSWITCH2; + const auto band = _map_freq_to_rx_band(freq); const bool is_lowband = (band == rx_band::LOWBAND); - const auto select_lowband_mixer_path = is_lowband ? - magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND : - magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_BYPASS; + const auto select_lowband_mixer_path = + is_lowband ? magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND + : magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_BYPASS; const bool enable_lowband_mixer = is_lowband; const bool rx_lna1_enable = - not bypass_lnas and ( - band == rx_band::BAND4 or - band == rx_band::BAND5 or - band == rx_band::BAND6); + not bypass_lnas + and (band == rx_band::BAND4 or band == rx_band::BAND5 or band == rx_band::BAND6); const bool rx_lna2_enable = not bypass_lnas and not rx_lna1_enable; UHD_LOG_TRACE(unique_id(), - " Enabling LNA1: " << (rx_lna1_enable ? "Yes" : "No") << - " Enabling LNA2: " << (rx_lna2_enable ? "Yes" : "No")); + " Enabling LNA1: " << (rx_lna1_enable ? "Yes" : "No") + << " Enabling LNA2: " << (rx_lna2_enable ? "Yes" : "No")); // All the defaults are OK when using the bypass path. if (not bypass_lnas) { - switch(band) { - case rx_band::LOWBAND: - case rx_band::BAND0: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0490LPMHZ; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0490LPMHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - break; - case rx_band::BAND1: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0440X0530MHZ; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - break; - case rx_band::BAND2: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0650X1000MHZ; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0650X1000MHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - break; - case rx_band::BAND3: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER1100X1575MHZ; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - break; - case rx_band::BAND4: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER1600X2250MHZ; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER1600X2250MHZFROM; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; - break; - case rx_band::BAND5: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER2100X2850MHZ; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; - break; - case rx_band::BAND6: - rx_sw2 = magnesium_cpld_ctrl::RX_SW2_UPPERFILTERBANKTOSWITCH4; - rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; - rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; - rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; - rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; - break; - case rx_band::INVALID_BAND: - UHD_LOG_ERROR(unique_id(), - "Cannot map RX frequency to band: " << freq); - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (band) { + case rx_band::LOWBAND: + case rx_band::BAND0: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0490LPMHZ; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0490LPMHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; + break; + case rx_band::BAND1: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0440X0530MHZ; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; + break; + case rx_band::BAND2: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0650X1000MHZ; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0650X1000MHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; + break; + case rx_band::BAND3: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER1100X1575MHZ; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; + break; + case rx_band::BAND4: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER1600X2250MHZ; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER1600X2250MHZFROM; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; + break; + case rx_band::BAND5: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER2100X2850MHZ; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; + break; + case rx_band::BAND6: + rx_sw2 = magnesium_cpld_ctrl::RX_SW2_UPPERFILTERBANKTOSWITCH4; + rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; + rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; + rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; + rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; + break; + case rx_band::INVALID_BAND: + UHD_LOG_ERROR(unique_id(), "Cannot map RX frequency to band: " << freq); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } - _cpld->set_rx_lna_atr_bits( - chan_sel, + _cpld->set_rx_lna_atr_bits(chan_sel, magnesium_cpld_ctrl::ANY, rx_lna1_enable, rx_lna2_enable, true /* defer commit */ ); - _cpld->set_rx_switches( - chan_sel, + _cpld->set_rx_switches(chan_sel, rx_sw2, rx_sw3, rx_sw4, rx_sw5, rx_sw6, select_lowband_mixer_path, - enable_lowband_mixer - ); + enable_lowband_mixer); } -void magnesium_radio_ctrl_impl::_update_tx_freq_switches( - const double freq, +void magnesium_radio_ctrl_impl::_update_tx_freq_switches(const double freq, const bool bypass_amp, - const magnesium_cpld_ctrl::chan_sel_t chan_sel -){ + const magnesium_cpld_ctrl::chan_sel_t chan_sel) +{ UHD_LOG_TRACE(unique_id(), - "Update all TX freq related switches. f=" << freq << " Hz, " - "bypass amp: " << (bypass_amp ? "Yes" : "No") << ", chan=" << chan_sel - ); - auto tx_sw1 = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1; - auto tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ; - auto tx_sw3 = magnesium_cpld_ctrl::TX_SW3_BYPASSPATHTOTRXSW; - const auto band = _map_freq_to_tx_band(freq); + "Update all TX freq related switches. f=" << freq + << " Hz, " + "bypass amp: " + << (bypass_amp ? "Yes" : "No") + << ", chan=" << chan_sel); + auto tx_sw1 = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1; + auto tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ; + auto tx_sw3 = magnesium_cpld_ctrl::TX_SW3_BYPASSPATHTOTRXSW; + const auto band = _map_freq_to_tx_band(freq); const bool is_lowband = (band == tx_band::LOWBAND); - const auto select_lowband_mixer_path = is_lowband ? - magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND : - magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_BYPASS; + const auto select_lowband_mixer_path = + is_lowband ? magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND + : magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_BYPASS; const bool enable_lowband_mixer = is_lowband; // Defaults are fine for bypassing the amp stage if (bypass_amp) { _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_BYPASSPATHTOTXSW3; } else { - // Set filters based on frequency - switch(band) { - case tx_band::LOWBAND: - _sw_trx[chan_sel] = - magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; - tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP0800MHZ; - tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP0800MHZ; - tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - break; - case tx_band::BAND0: - _sw_trx[chan_sel] = - magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; - tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP0800MHZ; - tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP0800MHZ; - tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - break; - case tx_band::BAND1: - _sw_trx[chan_sel] = - magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; - tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP1700MHZ; - tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP1700MHZ; - tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - break; - case tx_band::BAND2: - _sw_trx[chan_sel] = - magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; - tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP3400MHZ; - tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP3400MHZ; - tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - break; - case tx_band::BAND3: - _sw_trx[chan_sel] = - magnesium_cpld_ctrl::SW_TRX_FROMTXUPPERFILTERBANKLP6400MHZ; - tx_sw1 = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1; - tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ; - tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - break; - case tx_band::INVALID_BAND: - UHD_LOG_ERROR(unique_id(), - "Cannot map TX frequency to band: " << freq); - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + // Set filters based on frequency + switch (band) { + case tx_band::LOWBAND: + _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; + tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP0800MHZ; + tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP0800MHZ; + tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; + break; + case tx_band::BAND0: + _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; + tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP0800MHZ; + tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP0800MHZ; + tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; + break; + case tx_band::BAND1: + _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; + tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP1700MHZ; + tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP1700MHZ; + tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; + break; + case tx_band::BAND2: + _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; + tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP3400MHZ; + tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP3400MHZ; + tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; + break; + case tx_band::BAND3: + _sw_trx[chan_sel] = + magnesium_cpld_ctrl::SW_TRX_FROMTXUPPERFILTERBANKLP6400MHZ; + tx_sw1 = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1; + tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ; + tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; + break; + case tx_band::INVALID_BAND: + UHD_LOG_ERROR(unique_id(), "Cannot map TX frequency to band: " << freq); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } _cpld->set_trx_sw_atr_bits( - chan_sel, - magnesium_cpld_ctrl::ON, - _sw_trx[chan_sel], - true /* defer commit */ + chan_sel, magnesium_cpld_ctrl::ON, _sw_trx[chan_sel], true /* defer commit */ ); - _cpld->set_tx_switches( - chan_sel, + _cpld->set_tx_switches(chan_sel, tx_sw1, tx_sw2, tx_sw3, select_lowband_mixer_path, enable_lowband_mixer, - magnesium_cpld_ctrl::ON - ); + magnesium_cpld_ctrl::ON); } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp index e58e1706e..1370fde3a 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp @@ -4,9 +4,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "magnesium_radio_ctrl_impl.hpp" -#include "magnesium_gain_table.hpp" #include "magnesium_constants.hpp" +#include "magnesium_gain_table.hpp" +#include "magnesium_radio_ctrl_impl.hpp" #include <uhd/utils/log.hpp> using namespace uhd; @@ -15,72 +15,69 @@ using namespace uhd::rfnoc; using namespace magnesium; double magnesium_radio_ctrl_impl::_set_all_gain( - const double gain, - const double freq, - const size_t chan, - const direction_t dir -) { + const double gain, const double freq, const size_t chan, const direction_t dir) +{ UHD_LOG_TRACE(unique_id(), - __func__ << "(gain=" << gain << "dB, " - "freq=" << freq << " Hz, " - "chan=" << chan << ", " - "dir=" << dir); + __func__ << "(gain=" << gain + << "dB, " + "freq=" + << freq + << " Hz, " + "chan=" + << chan + << ", " + "dir=" + << dir); const size_t ad9371_chan = chan; - auto chan_sel = static_cast<magnesium_cpld_ctrl::chan_sel_t>(chan); - gain_tuple_t gain_tuple = (dir == RX_DIRECTION) ? - get_rx_gain_tuple(gain, _map_freq_to_rx_band(freq)): - get_tx_gain_tuple(gain, _map_freq_to_tx_band(freq)); + auto chan_sel = static_cast<magnesium_cpld_ctrl::chan_sel_t>(chan); + gain_tuple_t gain_tuple = (dir == RX_DIRECTION) + ? get_rx_gain_tuple(gain, _map_freq_to_rx_band(freq)) + : get_tx_gain_tuple(gain, _map_freq_to_tx_band(freq)); - if (_gain_profile[dir] == "manual"){ + if (_gain_profile[dir] == "manual") { UHD_LOG_TRACE(unique_id(), "Manual gain mode. Getting gain from property tree."); - gain_tuple = { - DSA_MAX_GAIN - _dsa_att[dir], - ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) - _ad9371_att[dir], + gain_tuple = {DSA_MAX_GAIN - _dsa_att[dir], + ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) + - _ad9371_att[dir], _amp_bypass[dir]}; - }else if (_gain_profile[dir] == "default"){ + } else if (_gain_profile[dir] == "default") { UHD_LOG_TRACE(unique_id(), "Getting gain from gain table."); - }else { - UHD_LOG_ERROR(unique_id(), "Unsupported gain mode: " << _gain_profile[dir]) + } else { + UHD_LOG_ERROR(unique_id(), "Unsupported gain mode: " << _gain_profile[dir]) } const double ad9371_gain = - ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) + ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) - gain_tuple.ad9371_att; UHD_LOG_TRACE(unique_id(), - "AD9371 attenuation==" << gain_tuple.ad9371_att << " dB, " - "AD9371 gain==" << ad9371_gain << " dB, " - "DSA attenuation == " << gain_tuple.dsa_att << " dB." - ); + "AD9371 attenuation==" << gain_tuple.ad9371_att + << " dB, " + "AD9371 gain==" + << ad9371_gain + << " dB, " + "DSA attenuation == " + << gain_tuple.dsa_att << " dB."); _ad9371->set_gain(ad9371_gain, ad9371_chan, dir); _dsa_set_att(gain_tuple.dsa_att, chan, dir); if (dir == RX_DIRECTION or dir == DX_DIRECTION) { - _all_rx_gain = gain; + _all_rx_gain = gain; _rx_bypass_lnas = gain_tuple.bypass; - _update_rx_freq_switches( - this->get_rx_frequency(chan), - _rx_bypass_lnas, - chan_sel - ); + _update_rx_freq_switches(this->get_rx_frequency(chan), _rx_bypass_lnas, chan_sel); } if (dir == TX_DIRECTION or dir == DX_DIRECTION) { - _all_tx_gain = gain; + _all_tx_gain = gain; _tx_bypass_amp = gain_tuple.bypass; - _update_tx_freq_switches( - this->get_tx_frequency(chan), - _tx_bypass_amp, - chan_sel - ); + _update_tx_freq_switches(this->get_tx_frequency(chan), _tx_bypass_amp, chan_sel); } return gain; } double magnesium_radio_ctrl_impl::_get_all_gain( - const size_t /* chan */, - const direction_t dir -) { + const size_t /* chan */, const direction_t dir) +{ UHD_LOG_TRACE(unique_id(), "Getting all gain "); if (dir == RX_DIRECTION) { - return _all_rx_gain; + return _all_rx_gain; } return _all_tx_gain; } @@ -89,14 +86,12 @@ double magnesium_radio_ctrl_impl::_get_all_gain( * DSA Controls *****************************************************************************/ double magnesium_radio_ctrl_impl::_dsa_set_att( - const double att, - const size_t chan, - const direction_t dir -) { + const double att, const size_t chan, const direction_t dir) +{ UHD_LOG_TRACE(unique_id(), - __func__ << - "(att=" << "att dB, chan=" << chan << ", dir=" << dir << ")") - const uint32_t dsa_val = 2*att; + __func__ << "(att=" + << "att dB, chan=" << chan << ", dir=" << dir << ")") + const uint32_t dsa_val = 2 * att; _set_dsa_val(chan, dir, dsa_val); if (dir == RX_DIRECTION or dir == DX_DIRECTION) { @@ -109,33 +104,29 @@ double magnesium_radio_ctrl_impl::_dsa_set_att( } double magnesium_radio_ctrl_impl::_dsa_get_att( - const size_t /*chan*/, - const direction_t dir -) { + const size_t /*chan*/, const direction_t dir) +{ if (dir == RX_DIRECTION) { - return _dsa_rx_att; + return _dsa_rx_att; } return _dsa_tx_att; } void magnesium_radio_ctrl_impl::_set_dsa_val( - const size_t chan, - const direction_t dir, - const uint32_t dsa_val -) { + const size_t chan, const direction_t dir, const uint32_t dsa_val) +{ // The DSA register holds 12 bits. The lower 6 bits are for RX, the upper // 6 bits are for TX. - if (dir == RX_DIRECTION or dir == DX_DIRECTION){ + if (dir == RX_DIRECTION or dir == DX_DIRECTION) { UHD_LOG_TRACE(unique_id(), __func__ << "(chan=" << chan << ", dir=RX" - << ", dsa_val=" << dsa_val << ")") + << ", dsa_val=" << dsa_val << ")") _gpio[chan]->set_gpio_out(dsa_val, 0x003F); } - if (dir == TX_DIRECTION or dir == DX_DIRECTION){ + if (dir == TX_DIRECTION or dir == DX_DIRECTION) { UHD_LOG_TRACE(unique_id(), __func__ << "(chan=" << chan << ", dir=TX" - << ", dsa_val=" << dsa_val << ")") - _gpio[chan]->set_gpio_out(dsa_val<<6, 0x0FC0); + << ", dsa_val=" << dsa_val << ")") + _gpio[chan]->set_gpio_out(dsa_val << 6, 0x0FC0); } } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp index 952cebdf8..c216b0777 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp @@ -7,20 +7,20 @@ #include "magnesium_radio_ctrl_impl.hpp" #include "magnesium_constants.hpp" #include "magnesium_gain_table.hpp" -#include <uhd/utils/log.hpp> +#include <uhd/exception.hpp> #include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/transport/chdr.hpp> -#include <uhd/utils/algorithm.hpp> -#include <uhd/utils/math.hpp> #include <uhd/types/direction.hpp> #include <uhd/types/eeprom.hpp> -#include <uhd/exception.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <boost/algorithm/string.hpp> -#include <boost/make_shared.hpp> #include <boost/format.hpp> -#include <sstream> +#include <boost/make_shared.hpp> #include <cmath> #include <cstdlib> +#include <sstream> using namespace uhd; using namespace uhd::usrp; @@ -28,76 +28,69 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - /************************************************************************** - * ADF4351 Controls - *************************************************************************/ - /*! - * \param lo_iface Reference to the LO object - * \param freq Frequency (in Hz) of the tone to be generated from the LO - * \param ref_clock_freq Frequency (in Hz) of the reference clock at the - * PLL input of the LO - * \param int_n_mode Integer-N mode on or off - */ - double _lo_set_frequency( - adf435x_iface::sptr lo_iface, - const double freq, - const double ref_clock_freq, - const bool int_n_mode - ) { - UHD_LOG_TRACE("MG/ADF4351", - "Attempting to tune low band LO to " << freq << - " Hz with ref clock freq " << ref_clock_freq); - lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); - lo_iface->set_reference_freq(ref_clock_freq); - lo_iface->set_prescaler(adf435x_iface::PRESCALER_4_5); - const double actual_freq = lo_iface->set_frequency(freq, int_n_mode); - lo_iface->set_output_power( - adf435x_iface::RF_OUTPUT_A, - adf435x_iface::OUTPUT_POWER_2DBM - ); - lo_iface->set_output_power( - adf435x_iface::RF_OUTPUT_B, - adf435x_iface::OUTPUT_POWER_2DBM - ); - lo_iface->set_charge_pump_current( - adf435x_iface::CHARGE_PUMP_CURRENT_0_31MA); - return actual_freq; - } - - /*! Configure and enable LO - * - * Will tune it to requested frequency and enable outputs. - * - * \param lo_iface Reference to the LO object - * \param lo_freq Frequency (in Hz) of the tone to be generated from the LO - * \param ref_clock_freq Frequency (in Hz) of the reference clock at the - * PLL input of the LO - * \param int_n_mode Integer-N mode on or off - * \returns the actual frequency the LO is running at - */ - double _lo_enable( - adf435x_iface::sptr lo_iface, - const double lo_freq, - const double ref_clock_freq, - const bool int_n_mode - ) { - const double actual_lo_freq = - _lo_set_frequency(lo_iface, lo_freq, ref_clock_freq, int_n_mode); - lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_A, true); - lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_B, true); - lo_iface->commit(); - return actual_lo_freq; - } +/************************************************************************** + * ADF4351 Controls + *************************************************************************/ +/*! + * \param lo_iface Reference to the LO object + * \param freq Frequency (in Hz) of the tone to be generated from the LO + * \param ref_clock_freq Frequency (in Hz) of the reference clock at the + * PLL input of the LO + * \param int_n_mode Integer-N mode on or off + */ +double _lo_set_frequency(adf435x_iface::sptr lo_iface, + const double freq, + const double ref_clock_freq, + const bool int_n_mode) +{ + UHD_LOG_TRACE("MG/ADF4351", + "Attempting to tune low band LO to " << freq << " Hz with ref clock freq " + << ref_clock_freq); + lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); + lo_iface->set_reference_freq(ref_clock_freq); + lo_iface->set_prescaler(adf435x_iface::PRESCALER_4_5); + const double actual_freq = lo_iface->set_frequency(freq, int_n_mode); + lo_iface->set_output_power( + adf435x_iface::RF_OUTPUT_A, adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power( + adf435x_iface::RF_OUTPUT_B, adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_charge_pump_current(adf435x_iface::CHARGE_PUMP_CURRENT_0_31MA); + return actual_freq; +} + +/*! Configure and enable LO + * + * Will tune it to requested frequency and enable outputs. + * + * \param lo_iface Reference to the LO object + * \param lo_freq Frequency (in Hz) of the tone to be generated from the LO + * \param ref_clock_freq Frequency (in Hz) of the reference clock at the + * PLL input of the LO + * \param int_n_mode Integer-N mode on or off + * \returns the actual frequency the LO is running at + */ +double _lo_enable(adf435x_iface::sptr lo_iface, + const double lo_freq, + const double ref_clock_freq, + const bool int_n_mode) +{ + const double actual_lo_freq = + _lo_set_frequency(lo_iface, lo_freq, ref_clock_freq, int_n_mode); + lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_A, true); + lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_B, true); + lo_iface->commit(); + return actual_lo_freq; +} - /*! Disable LO - */ - void _lo_disable(adf435x_iface::sptr lo_iface) - { - lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_A, false); - lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_B, false); - lo_iface->commit(); - } +/*! Disable LO + */ +void _lo_disable(adf435x_iface::sptr lo_iface) +{ + lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_A, false); + lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_B, false); + lo_iface->commit(); } +} // namespace /****************************************************************************** @@ -107,10 +100,9 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl) { UHD_LOG_TRACE(unique_id(), "Entering magnesium_radio_ctrl_impl ctor..."); const char radio_slot_name[2] = {'A', 'B'}; - _radio_slot = radio_slot_name[get_block_id().get_block_count()]; + _radio_slot = radio_slot_name[get_block_id().get_block_count()]; UHD_LOG_TRACE(unique_id(), "Radio slot: " << _radio_slot); - _rpc_prefix = - (_radio_slot == "A") ? "db_0_" : "db_1_"; + _rpc_prefix = (_radio_slot == "A") ? "db_0_" : "db_1_"; _init_defaults(); _init_peripherals(); @@ -135,17 +127,16 @@ double magnesium_radio_ctrl_impl::set_rate(double requested_rate) const double rate = rates.clip(requested_rate); if (!math::frequencies_are_equal(requested_rate, rate)) { - UHD_LOG_WARNING(unique_id(), - "Coercing requested sample rate from " << (requested_rate/1e6) << - " to " << (rate/1e6) - ); + UHD_LOG_WARNING(unique_id(), + "Coercing requested sample rate from " << (requested_rate / 1e6) << " to " + << (rate / 1e6)); } const double current_rate = get_rate(); if (math::frequencies_are_equal(current_rate, rate)) { - UHD_LOG_DEBUG(unique_id(), - "Rate is already at " << rate << ". Skipping set_rate()"); - return current_rate; + UHD_LOG_DEBUG( + unique_id(), "Rate is already at " << rate << ". Skipping set_rate()"); + return current_rate; } std::lock_guard<std::mutex> l(_set_lock); @@ -159,84 +150,72 @@ double magnesium_radio_ctrl_impl::set_rate(double requested_rate) set_tx_frequency(get_tx_frequency(0), 0); // Gain and bandwidth need to be looped: for (size_t radio_idx = 0; radio_idx < _get_num_radios(); radio_idx++) { - set_rx_gain(get_rx_gain(radio_idx), radio_idx); - set_tx_gain(get_rx_gain(radio_idx), radio_idx); - set_rx_bandwidth(get_rx_bandwidth(radio_idx), radio_idx); - set_tx_bandwidth(get_tx_bandwidth(radio_idx), radio_idx); + set_rx_gain(get_rx_gain(radio_idx), radio_idx); + set_tx_gain(get_rx_gain(radio_idx), radio_idx); + set_rx_bandwidth(get_rx_bandwidth(radio_idx), radio_idx); + set_tx_bandwidth(get_tx_bandwidth(radio_idx), radio_idx); } radio_ctrl_impl::set_rate(new_rate); return new_rate; } -void magnesium_radio_ctrl_impl::set_tx_antenna( - const std::string &ant, - const size_t chan -) { +void magnesium_radio_ctrl_impl::set_tx_antenna(const std::string& ant, const size_t chan) +{ if (ant != get_tx_antenna(chan)) { - throw uhd::value_error(str( - boost::format("[%s] Requesting invalid TX antenna value: %s") - % unique_id() - % ant - )); + throw uhd::value_error( + str(boost::format("[%s] Requesting invalid TX antenna value: %s") + % unique_id() % ant)); } // We can't actually set the TX antenna, so let's stop here. } -void magnesium_radio_ctrl_impl::set_rx_antenna( - const std::string &ant, - const size_t chan -) { +void magnesium_radio_ctrl_impl::set_rx_antenna(const std::string& ant, const size_t chan) +{ UHD_ASSERT_THROW(chan <= MAGNESIUM_NUM_CHANS); - if (std::find(MAGNESIUM_RX_ANTENNAS.begin(), - MAGNESIUM_RX_ANTENNAS.end(), - ant) == MAGNESIUM_RX_ANTENNAS.end()) { - throw uhd::value_error(str( - boost::format("[%s] Requesting invalid RX antenna value: %s") - % unique_id() - % ant - )); - } - UHD_LOG_TRACE(unique_id(), - "Setting RX antenna to " << ant << " for chan " << chan); - magnesium_cpld_ctrl::chan_sel_t chan_sel = - chan == 0 ? magnesium_cpld_ctrl::CHAN1 : magnesium_cpld_ctrl::CHAN2; + if (std::find(MAGNESIUM_RX_ANTENNAS.begin(), MAGNESIUM_RX_ANTENNAS.end(), ant) + == MAGNESIUM_RX_ANTENNAS.end()) { + throw uhd::value_error( + str(boost::format("[%s] Requesting invalid RX antenna value: %s") + % unique_id() % ant)); + } + UHD_LOG_TRACE(unique_id(), "Setting RX antenna to " << ant << " for chan " << chan); + magnesium_cpld_ctrl::chan_sel_t chan_sel = chan == 0 ? magnesium_cpld_ctrl::CHAN1 + : magnesium_cpld_ctrl::CHAN2; _update_atr_switches(chan_sel, RX_DIRECTION, ant); radio_ctrl_impl::set_rx_antenna(ant, chan); } double magnesium_radio_ctrl_impl::set_tx_frequency( - const double req_freq, - const size_t chan -) { + const double req_freq, const size_t chan) +{ const double freq = MAGNESIUM_FREQ_RANGE.clip(req_freq); - UHD_LOG_TRACE(unique_id(), - "set_tx_frequency(f=" << freq << ", chan=" << chan << ")"); - _desired_rf_freq[TX_DIRECTION]=freq; + UHD_LOG_TRACE(unique_id(), "set_tx_frequency(f=" << freq << ", chan=" << chan << ")"); + _desired_rf_freq[TX_DIRECTION] = freq; std::lock_guard<std::mutex> l(_set_lock); // We need to set the switches on both channels, because they share an LO. // This way, if we tune channel 0 it will not put channel 1 into a bad // state. _update_tx_freq_switches(freq, _tx_bypass_amp, magnesium_cpld_ctrl::BOTH); - const std::string ad9371_source = this->get_tx_lo_source(MAGNESIUM_LO1, chan); + const std::string ad9371_source = this->get_tx_lo_source(MAGNESIUM_LO1, chan); const std::string adf4351_source = this->get_tx_lo_source(MAGNESIUM_LO2, chan); UHD_ASSERT_THROW(adf4351_source == "internal"); double coerced_if_freq = freq; if (_map_freq_to_tx_band(freq) == tx_band::LOWBAND) { - _is_low_band[TX_DIRECTION] = true; + _is_low_band[TX_DIRECTION] = true; const double desired_low_freq = MAGNESIUM_TX_IF_FREQ - freq; coerced_if_freq = - this->_set_tx_lo_freq(adf4351_source, MAGNESIUM_LO2, desired_low_freq, chan) + freq; + this->_set_tx_lo_freq(adf4351_source, MAGNESIUM_LO2, desired_low_freq, chan) + + freq; UHD_LOG_TRACE(unique_id(), "coerced_if_freq = " << coerced_if_freq); } else { _is_low_band[TX_DIRECTION] = false; _lo_disable(_tx_lo); } // external LO required to tune at 2xdesired_frequency. - const double desired_if_freq = (ad9371_source == "internal") ? - coerced_if_freq : - 2*coerced_if_freq; + const double desired_if_freq = (ad9371_source == "internal") ? coerced_if_freq + : 2 * coerced_if_freq; this->_set_tx_lo_freq(ad9371_source, MAGNESIUM_LO1, desired_if_freq, chan); this->_update_freq(chan, TX_DIRECTION); @@ -245,81 +224,69 @@ double magnesium_radio_ctrl_impl::set_tx_frequency( } void magnesium_radio_ctrl_impl::_update_gain( - const size_t chan, - const uhd::direction_t dir -) { - const std::string fe = - (dir == TX_DIRECTION) ? "tx_frontends" : "rx_frontends"; - const double freq = (dir == TX_DIRECTION) ? - this->get_tx_frequency(chan) : - this->get_rx_frequency(chan); + const size_t chan, const uhd::direction_t dir) +{ + const std::string fe = (dir == TX_DIRECTION) ? "tx_frontends" : "rx_frontends"; + const double freq = (dir == TX_DIRECTION) ? this->get_tx_frequency(chan) + : this->get_rx_frequency(chan); this->_set_all_gain(this->_get_all_gain(chan, dir), freq, chan, dir); } void magnesium_radio_ctrl_impl::_update_freq( - const size_t chan, - const uhd::direction_t dir -) { - const std::string ad9371_source = dir == TX_DIRECTION ? - this->get_tx_lo_source(MAGNESIUM_LO1, chan) : - this->get_rx_lo_source(MAGNESIUM_LO1, chan) - ; - - const double ad9371_freq = ad9371_source == "external" ? - _ad9371_freq[dir]/2 : - _ad9371_freq[dir] - ; - const double rf_freq = _is_low_band[dir] ? - ad9371_freq - _adf4351_freq[dir] : - ad9371_freq - ; - - UHD_LOG_TRACE(unique_id(), - "RF freq = " << rf_freq); - UHD_ASSERT_THROW(fp_compare_epsilon<double>(rf_freq) >= 0); - UHD_ASSERT_THROW( - fp_compare_epsilon<double>(std::abs(rf_freq - _desired_rf_freq[dir])) <= _master_clock_rate/2); - if (dir == RX_DIRECTION){ + const size_t chan, const uhd::direction_t dir) +{ + const std::string ad9371_source = dir == TX_DIRECTION + ? this->get_tx_lo_source(MAGNESIUM_LO1, chan) + : this->get_rx_lo_source(MAGNESIUM_LO1, chan); + + const double ad9371_freq = ad9371_source == "external" ? _ad9371_freq[dir] / 2 + : _ad9371_freq[dir]; + const double rf_freq = _is_low_band[dir] ? ad9371_freq - _adf4351_freq[dir] + : ad9371_freq; + + UHD_LOG_TRACE(unique_id(), "RF freq = " << rf_freq); + UHD_ASSERT_THROW(fp_compare_epsilon<double>(rf_freq) >= 0); + UHD_ASSERT_THROW(fp_compare_epsilon<double>(std::abs(rf_freq - _desired_rf_freq[dir])) + <= _master_clock_rate / 2); + if (dir == RX_DIRECTION) { radio_ctrl_impl::set_rx_frequency(rf_freq, chan); - }else if (dir == TX_DIRECTION){ + } else if (dir == TX_DIRECTION) { radio_ctrl_impl::set_tx_frequency(rf_freq, chan); - }else{ + } else { UHD_THROW_INVALID_CODE_PATH(); } } double magnesium_radio_ctrl_impl::set_rx_frequency( - const double req_freq, - const size_t chan -) { + const double req_freq, const size_t chan) +{ const double freq = MAGNESIUM_FREQ_RANGE.clip(req_freq); - UHD_LOG_TRACE(unique_id(), - "set_rx_frequency(f=" << freq << ", chan=" << chan << ")"); - _desired_rf_freq[RX_DIRECTION]=freq; + UHD_LOG_TRACE(unique_id(), "set_rx_frequency(f=" << freq << ", chan=" << chan << ")"); + _desired_rf_freq[RX_DIRECTION] = freq; std::lock_guard<std::mutex> l(_set_lock); // We need to set the switches on both channels, because they share an LO. // This way, if we tune channel 0 it will not put channel 1 into a bad // state. _update_rx_freq_switches(freq, _rx_bypass_lnas, magnesium_cpld_ctrl::BOTH); - const std::string ad9371_source = this->get_rx_lo_source(MAGNESIUM_LO1, chan); + const std::string ad9371_source = this->get_rx_lo_source(MAGNESIUM_LO1, chan); const std::string adf4351_source = this->get_rx_lo_source(MAGNESIUM_LO2, chan); UHD_ASSERT_THROW(adf4351_source == "internal"); double coerced_if_freq = freq; if (_map_freq_to_rx_band(freq) == rx_band::LOWBAND) { - _is_low_band[RX_DIRECTION] = true; + _is_low_band[RX_DIRECTION] = true; const double desired_low_freq = MAGNESIUM_RX_IF_FREQ - freq; coerced_if_freq = - this->_set_rx_lo_freq(adf4351_source, MAGNESIUM_LO2, desired_low_freq, chan) + freq; + this->_set_rx_lo_freq(adf4351_source, MAGNESIUM_LO2, desired_low_freq, chan) + + freq; UHD_LOG_TRACE(unique_id(), "coerced_if_freq = " << coerced_if_freq); } else { _is_low_band[RX_DIRECTION] = false; _lo_disable(_rx_lo); } // external LO required to tune at 2xdesired_frequency. - const double desired_if_freq = ad9371_source == "internal" ? - coerced_if_freq : - 2*coerced_if_freq; + const double desired_if_freq = ad9371_source == "internal" ? coerced_if_freq + : 2 * coerced_if_freq; this->_set_rx_lo_freq(ad9371_source, MAGNESIUM_LO1, desired_if_freq, chan); @@ -329,25 +296,20 @@ double magnesium_radio_ctrl_impl::set_rx_frequency( return radio_ctrl_impl::get_rx_frequency(chan); } -double magnesium_radio_ctrl_impl::get_tx_frequency( - const size_t chan) +double magnesium_radio_ctrl_impl::get_tx_frequency(const size_t chan) { - UHD_LOG_TRACE(unique_id(), - "get_tx_frequency(chan=" << chan << ")"); + UHD_LOG_TRACE(unique_id(), "get_tx_frequency(chan=" << chan << ")"); return radio_ctrl_impl::get_tx_frequency(chan); } -double magnesium_radio_ctrl_impl::get_rx_frequency( - const size_t chan) +double magnesium_radio_ctrl_impl::get_rx_frequency(const size_t chan) { - UHD_LOG_TRACE(unique_id(), - "get_rx_frequency(chan=" << chan << ")"); + UHD_LOG_TRACE(unique_id(), "get_rx_frequency(chan=" << chan << ")"); return radio_ctrl_impl::get_rx_frequency(chan); } double magnesium_radio_ctrl_impl::set_rx_bandwidth( - const double bandwidth, - const size_t chan -) { + const double bandwidth, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); _ad9371->set_bandwidth(bandwidth, chan, RX_DIRECTION); // FIXME: setting analog bandwidth on AD9371 take no effect. @@ -359,9 +321,8 @@ double magnesium_radio_ctrl_impl::set_rx_bandwidth( } double magnesium_radio_ctrl_impl::set_tx_bandwidth( - const double bandwidth, - const size_t chan -) { + const double bandwidth, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); _ad9371->set_bandwidth(bandwidth, chan, TX_DIRECTION); // FIXME: setting analog bandwidth on AD9371 take no effect. @@ -369,182 +330,155 @@ double magnesium_radio_ctrl_impl::set_tx_bandwidth( UHD_LOG_WARNING(unique_id(), "set_tx_bandwidth take no effect on AD9371. " "Default analog bandwidth is 100MHz"); - return AD9371_TX_MAX_BANDWIDTH ; + return AD9371_TX_MAX_BANDWIDTH; } -double magnesium_radio_ctrl_impl::set_tx_gain( - const double gain, - const size_t chan -) { +double magnesium_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); - UHD_LOG_TRACE(unique_id(), - "set_tx_gain(gain=" << gain << ", chan=" << chan << ")"); - const double coerced_gain = _set_all_gain( - gain, - this->get_tx_frequency(chan), - chan, - TX_DIRECTION - ); + UHD_LOG_TRACE(unique_id(), "set_tx_gain(gain=" << gain << ", chan=" << chan << ")"); + const double coerced_gain = + _set_all_gain(gain, this->get_tx_frequency(chan), chan, TX_DIRECTION); radio_ctrl_impl::set_tx_gain(coerced_gain, chan); return coerced_gain; } double magnesium_radio_ctrl_impl::_set_tx_gain( - const std::string &name, - const double gain, - const size_t chan -) { + const std::string& name, const double gain, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); UHD_LOG_TRACE(unique_id(), "_set_tx_gain(name=" << name << ", gain=" << gain << ", chan=" << chan << ")"); - UHD_LOG_TRACE(unique_id(), + UHD_LOG_TRACE(unique_id(), "_set_tx_gain(name=" << name << ", gain=" << gain << ", chan=" << chan << ")"); double clip_gain = 0; - if (name == MAGNESIUM_GAIN1){ + if (name == MAGNESIUM_GAIN1) { clip_gain = uhd::clip(gain, AD9371_MIN_TX_GAIN, AD9371_MAX_TX_GAIN); _ad9371_att[TX_DIRECTION] = clip_gain; - }else if (name == MAGNESIUM_GAIN2){ - clip_gain = uhd::clip(gain, DSA_MIN_GAIN, DSA_MAX_GAIN); + } else if (name == MAGNESIUM_GAIN2) { + clip_gain = uhd::clip(gain, DSA_MIN_GAIN, DSA_MAX_GAIN); _dsa_att[TX_DIRECTION] = clip_gain; - }else if (name == MAGNESIUM_AMP){ - clip_gain = gain > 0.0 ? AMP_MAX_GAIN: AMP_MIN_GAIN; + } else if (name == MAGNESIUM_AMP) { + clip_gain = gain > 0.0 ? AMP_MAX_GAIN : AMP_MIN_GAIN; _amp_bypass[TX_DIRECTION] = clip_gain == 0.0; - }else { + } else { throw uhd::value_error("Could not find gain element " + name); } - UHD_LOG_TRACE(unique_id(), - "_set_tx_gain calling update gain"); - this->_set_all_gain( - this->_get_all_gain(chan, TX_DIRECTION), + UHD_LOG_TRACE(unique_id(), "_set_tx_gain calling update gain"); + this->_set_all_gain(this->_get_all_gain(chan, TX_DIRECTION), this->get_tx_frequency(chan), chan, - TX_DIRECTION - ); + TX_DIRECTION); return clip_gain; } double magnesium_radio_ctrl_impl::_get_tx_gain( - const std::string &name, - const size_t /*chan*/ -) { + const std::string& name, const size_t /*chan*/ +) +{ std::lock_guard<std::mutex> l(_set_lock); - if (name == MAGNESIUM_GAIN1){ + if (name == MAGNESIUM_GAIN1) { return _ad9371_att[TX_DIRECTION]; - }else if (name == MAGNESIUM_GAIN2){ + } else if (name == MAGNESIUM_GAIN2) { return _dsa_att[TX_DIRECTION]; - }else if (name == MAGNESIUM_AMP){ - return _amp_bypass[TX_DIRECTION]? AMP_MIN_GAIN : AMP_MAX_GAIN; - }else { + } else if (name == MAGNESIUM_AMP) { + return _amp_bypass[TX_DIRECTION] ? AMP_MIN_GAIN : AMP_MAX_GAIN; + } else { throw uhd::value_error("Could not find gain element " + name); } } -double magnesium_radio_ctrl_impl::set_rx_gain( - const double gain, - const size_t chan -) { +double magnesium_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); - UHD_LOG_TRACE(unique_id(), - "set_rx_gain(gain=" << gain << ", chan=" << chan << ")"); - const double coerced_gain = _set_all_gain( - gain, - this->get_rx_frequency(chan), - chan, - RX_DIRECTION - ); + UHD_LOG_TRACE(unique_id(), "set_rx_gain(gain=" << gain << ", chan=" << chan << ")"); + const double coerced_gain = + _set_all_gain(gain, this->get_rx_frequency(chan), chan, RX_DIRECTION); radio_ctrl_impl::set_rx_gain(coerced_gain, chan); return coerced_gain; } double magnesium_radio_ctrl_impl::_set_rx_gain( - const std::string &name, - const double gain, - const size_t chan -) { + const std::string& name, const double gain, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); UHD_LOG_TRACE(unique_id(), "_set_rx_gain(name=" << name << ", gain=" << gain << ", chan=" << chan << ")"); double clip_gain = 0; - if (name == MAGNESIUM_GAIN1){ + if (name == MAGNESIUM_GAIN1) { clip_gain = uhd::clip(gain, AD9371_MIN_RX_GAIN, AD9371_MAX_RX_GAIN); _ad9371_att[RX_DIRECTION] = clip_gain; - }else if (name == MAGNESIUM_GAIN2){ - clip_gain = uhd::clip(gain, DSA_MIN_GAIN, DSA_MAX_GAIN); + } else if (name == MAGNESIUM_GAIN2) { + clip_gain = uhd::clip(gain, DSA_MIN_GAIN, DSA_MAX_GAIN); _dsa_att[RX_DIRECTION] = clip_gain; - }else if (name == MAGNESIUM_AMP){ - clip_gain = gain > 0.0 ? AMP_MAX_GAIN: AMP_MIN_GAIN; + } else if (name == MAGNESIUM_AMP) { + clip_gain = gain > 0.0 ? AMP_MAX_GAIN : AMP_MIN_GAIN; _amp_bypass[RX_DIRECTION] = clip_gain == 0.0; - }else { + } else { throw uhd::value_error("Could not find gain element " + name); } - UHD_LOG_TRACE(unique_id(), - "_set_rx_gain calling update gain"); - this->_set_all_gain( - this->_get_all_gain(chan, RX_DIRECTION), + UHD_LOG_TRACE(unique_id(), "_set_rx_gain calling update gain"); + this->_set_all_gain(this->_get_all_gain(chan, RX_DIRECTION), this->get_rx_frequency(chan), chan, - RX_DIRECTION - ); + RX_DIRECTION); return clip_gain; // not really any coreced here (only clip) for individual gain } double magnesium_radio_ctrl_impl::_get_rx_gain( - const std::string &name, - const size_t /*chan*/ -) { + const std::string& name, const size_t /*chan*/ +) +{ std::lock_guard<std::mutex> l(_set_lock); - if (name == MAGNESIUM_GAIN1){ + if (name == MAGNESIUM_GAIN1) { return _ad9371_att[RX_DIRECTION]; - }else if (name == MAGNESIUM_GAIN2){ + } else if (name == MAGNESIUM_GAIN2) { return _dsa_att[RX_DIRECTION]; - }else if (name == MAGNESIUM_AMP){ - return _amp_bypass[RX_DIRECTION]? AMP_MIN_GAIN : AMP_MAX_GAIN; - }else{ + } else if (name == MAGNESIUM_AMP) { + return _amp_bypass[RX_DIRECTION] ? AMP_MIN_GAIN : AMP_MAX_GAIN; + } else { throw uhd::value_error("Could not find gain element " + name); } } -std::vector<std::string> magnesium_radio_ctrl_impl::get_rx_lo_names( - const size_t /*chan*/ -) { - return std::vector<std::string> {MAGNESIUM_LO1, MAGNESIUM_LO2}; +std::vector<std::string> magnesium_radio_ctrl_impl::get_rx_lo_names(const size_t /*chan*/ +) +{ + return std::vector<std::string>{MAGNESIUM_LO1, MAGNESIUM_LO2}; } std::vector<std::string> magnesium_radio_ctrl_impl::get_rx_lo_sources( - const std::string &name, - const size_t /*chan*/ -) { - if (name == MAGNESIUM_LO2){ - return std::vector<std::string> { "internal" }; - }else if (name == MAGNESIUM_LO1){ - return std::vector<std::string> { "internal", "external" }; - }else { + const std::string& name, const size_t /*chan*/ +) +{ + if (name == MAGNESIUM_LO2) { + return std::vector<std::string>{"internal"}; + } else if (name == MAGNESIUM_LO1) { + return std::vector<std::string>{"internal", "external"}; + } else { throw uhd::value_error("Could not find LO stage " + name); - } + } } freq_range_t magnesium_radio_ctrl_impl::get_rx_lo_freq_range( - const std::string & name, - const size_t /*chan*/ -) { - if (name == MAGNESIUM_LO1){ + const std::string& name, const size_t /*chan*/ +) +{ + if (name == MAGNESIUM_LO1) { return freq_range_t{ADF4351_MIN_FREQ, ADF4351_MAX_FREQ}; - } - else if(name == MAGNESIUM_LO2){ + } else if (name == MAGNESIUM_LO2) { return freq_range_t{AD9371_MIN_FREQ, AD9371_MAX_FREQ}; - } - else { + } else { throw uhd::value_error("Could not find LO stage " + name); } } void magnesium_radio_ctrl_impl::set_rx_lo_source( - const std::string &src, - const std::string &name, - const size_t /*chan*/ -) { - //TODO: checking what options are there + const std::string& src, const std::string& name, const size_t /*chan*/ +) +{ + // TODO: checking what options are there std::lock_guard<std::mutex> l(_set_lock); UHD_LOG_TRACE(unique_id(), "Setting RX LO " << name << " to " << src); @@ -552,180 +486,179 @@ void magnesium_radio_ctrl_impl::set_rx_lo_source( _ad9371->set_lo_source(src, RX_DIRECTION); } else { UHD_LOG_ERROR(unique_id(), - "RX LO " << name << " does not support setting source to " << src); + "RX LO " << name << " does not support setting source to " << src); } } const std::string magnesium_radio_ctrl_impl::get_rx_lo_source( - const std::string &name, - const size_t /*chan*/ -) { - if (name == MAGNESIUM_LO1){ - //TODO: should we use this from cache? + const std::string& name, const size_t /*chan*/ +) +{ + if (name == MAGNESIUM_LO1) { + // TODO: should we use this from cache? return _ad9371->get_lo_source(RX_DIRECTION); } return "internal"; } -double magnesium_radio_ctrl_impl::_set_rx_lo_freq( - const std::string source, +double magnesium_radio_ctrl_impl::_set_rx_lo_freq(const std::string source, const std::string name, const double freq, - const size_t chan -){ + const size_t chan) +{ double coerced_lo_freq = freq; - if (source != "internal"){ - UHD_LOG_WARNING(unique_id(), "LO source is not internal. This set frequency will be ignored"); - if(name == MAGNESIUM_LO1){ + if (source != "internal") { + UHD_LOG_WARNING( + unique_id(), "LO source is not internal. This set frequency will be ignored"); + if (name == MAGNESIUM_LO1) { // handle ad9371 external LO case - coerced_lo_freq = freq; + coerced_lo_freq = freq; _ad9371_freq[RX_DIRECTION] = coerced_lo_freq; } - }else { - if(name == MAGNESIUM_LO1){ - coerced_lo_freq = _ad9371->set_frequency(freq, chan, RX_DIRECTION); + } else { + if (name == MAGNESIUM_LO1) { + coerced_lo_freq = _ad9371->set_frequency(freq, chan, RX_DIRECTION); _ad9371_freq[RX_DIRECTION] = coerced_lo_freq; - }else if (name == MAGNESIUM_LO2 ){ + } else if (name == MAGNESIUM_LO2) { // TODO: no hardcode the init_n_mode - coerced_lo_freq = _lo_enable(_rx_lo, freq, _master_clock_rate, false); + coerced_lo_freq = _lo_enable(_rx_lo, freq, _master_clock_rate, false); _adf4351_freq[RX_DIRECTION] = coerced_lo_freq; - }else { - UHD_LOG_WARNING(unique_id(), "There's no LO with this name of "<<name << " in the system. This set rx lo freq will be ignored"); + } else { + UHD_LOG_WARNING(unique_id(), + "There's no LO with this name of " + << name << " in the system. This set rx lo freq will be ignored"); }; } return coerced_lo_freq; } double magnesium_radio_ctrl_impl::set_rx_lo_freq( - double freq, - const std::string &name, - const size_t chan -) { - UHD_LOG_TRACE(unique_id(), "Setting rx lo frequency for " <<name << " with freq = " <<freq); + double freq, const std::string& name, const size_t chan) +{ + UHD_LOG_TRACE( + unique_id(), "Setting rx lo frequency for " << name << " with freq = " << freq); std::lock_guard<std::mutex> l(_set_lock); - std::string source = this->get_rx_lo_source(name, chan); + std::string source = this->get_rx_lo_source(name, chan); const double coerced_lo_freq = this->_set_rx_lo_freq(source, name, freq, chan); - this->_update_freq(chan,RX_DIRECTION); - this->_update_gain(chan,RX_DIRECTION); + this->_update_freq(chan, RX_DIRECTION); + this->_update_gain(chan, RX_DIRECTION); return coerced_lo_freq; } double magnesium_radio_ctrl_impl::get_rx_lo_freq( - const std::string & name, - const size_t chan -) { - - UHD_LOG_TRACE(unique_id(),"Getting rx lo frequency for " <<name); - std::string source = this->get_rx_lo_source(name,chan); - if(name == MAGNESIUM_LO1){ + const std::string& name, const size_t chan) +{ + UHD_LOG_TRACE(unique_id(), "Getting rx lo frequency for " << name); + std::string source = this->get_rx_lo_source(name, chan); + if (name == MAGNESIUM_LO1) { return _ad9371_freq[RX_DIRECTION]; - }else if (name == "adf4531" ){ + } else if (name == "adf4531") { return _adf4351_freq[RX_DIRECTION]; - }else { - UHD_LOG_ERROR(unique_id(), "There's no LO with this name of "<<name << " in the system. This set rx lo freq will be ignored"); + } else { + UHD_LOG_ERROR(unique_id(), + "There's no LO with this name of " + << name << " in the system. This set rx lo freq will be ignored"); } UHD_THROW_INVALID_CODE_PATH(); } -//TX LO -std::vector<std::string> magnesium_radio_ctrl_impl::get_tx_lo_names( - const size_t /*chan*/ -) { - return std::vector<std::string> {MAGNESIUM_LO1, MAGNESIUM_LO2}; +// TX LO +std::vector<std::string> magnesium_radio_ctrl_impl::get_tx_lo_names(const size_t /*chan*/ +) +{ + return std::vector<std::string>{MAGNESIUM_LO1, MAGNESIUM_LO2}; } std::vector<std::string> magnesium_radio_ctrl_impl::get_tx_lo_sources( - const std::string &name, - const size_t /*chan*/ -) { - if (name == MAGNESIUM_LO2){ - return std::vector<std::string> { "internal" }; - }else if (name == MAGNESIUM_LO1){ - return std::vector<std::string> { "internal", "external" }; - }else { + const std::string& name, const size_t /*chan*/ +) +{ + if (name == MAGNESIUM_LO2) { + return std::vector<std::string>{"internal"}; + } else if (name == MAGNESIUM_LO1) { + return std::vector<std::string>{"internal", "external"}; + } else { throw uhd::value_error("Could not find LO stage " + name); - } + } } freq_range_t magnesium_radio_ctrl_impl::get_tx_lo_freq_range( - const std::string &name, - const size_t /*chan*/ -) { - if (name == MAGNESIUM_LO2){ + const std::string& name, const size_t /*chan*/ +) +{ + if (name == MAGNESIUM_LO2) { return freq_range_t{ADF4351_MIN_FREQ, ADF4351_MAX_FREQ}; - } - else if(name == MAGNESIUM_LO1){ + } else if (name == MAGNESIUM_LO1) { return freq_range_t{AD9371_MIN_FREQ, AD9371_MAX_FREQ}; - } - else { + } else { throw uhd::value_error("Could not find LO stage " + name); } } void magnesium_radio_ctrl_impl::set_tx_lo_source( - const std::string &src, - const std::string &name, - const size_t /*chan*/ -) { - //TODO: checking what options are there + const std::string& src, const std::string& name, const size_t /*chan*/ +) +{ + // TODO: checking what options are there std::lock_guard<std::mutex> l(_set_lock); UHD_LOG_TRACE(unique_id(), "Setting TX LO " << name << " to " << src); if (name == MAGNESIUM_LO1) { _ad9371->set_lo_source(src, TX_DIRECTION); } else { UHD_LOG_ERROR(unique_id(), - "TX LO " << name << " does not support setting source to " << src); + "TX LO " << name << " does not support setting source to " << src); } } const std::string magnesium_radio_ctrl_impl::get_tx_lo_source( - const std::string &name, - const size_t /*chan*/ -) { - if (name == MAGNESIUM_LO1){ - //TODO: should we use this from cache? + const std::string& name, const size_t /*chan*/ +) +{ + if (name == MAGNESIUM_LO1) { + // TODO: should we use this from cache? return _ad9371->get_lo_source(TX_DIRECTION); } return "internal"; } -double magnesium_radio_ctrl_impl::_set_tx_lo_freq( - const std::string source, +double magnesium_radio_ctrl_impl::_set_tx_lo_freq(const std::string source, const std::string name, const double freq, - const size_t chan -){ + const size_t chan) +{ double coerced_lo_freq = freq; - if (source != "internal"){ - UHD_LOG_WARNING(unique_id(), "LO source is not internal. This set frequency will be ignored"); - if(name == MAGNESIUM_LO1){ + if (source != "internal") { + UHD_LOG_WARNING( + unique_id(), "LO source is not internal. This set frequency will be ignored"); + if (name == MAGNESIUM_LO1) { // handle ad9371 external LO case - coerced_lo_freq = freq; + coerced_lo_freq = freq; _ad9371_freq[TX_DIRECTION] = coerced_lo_freq; } - }else { - if(name == MAGNESIUM_LO1){ - coerced_lo_freq = _ad9371->set_frequency(freq, chan, TX_DIRECTION); + } else { + if (name == MAGNESIUM_LO1) { + coerced_lo_freq = _ad9371->set_frequency(freq, chan, TX_DIRECTION); _ad9371_freq[TX_DIRECTION] = coerced_lo_freq; - }else if (name == MAGNESIUM_LO2 ){ + } else if (name == MAGNESIUM_LO2) { // TODO: no hardcode the int_n_mode const bool int_n_mode = false; coerced_lo_freq = _lo_enable(_tx_lo, freq, _master_clock_rate, int_n_mode); _adf4351_freq[TX_DIRECTION] = coerced_lo_freq; - }else { - UHD_LOG_WARNING(unique_id(), "There's no LO with this name of "<<name << " in the system. This set tx lo freq will be ignored"); + } else { + UHD_LOG_WARNING(unique_id(), + "There's no LO with this name of " + << name << " in the system. This set tx lo freq will be ignored"); }; } return coerced_lo_freq; } double magnesium_radio_ctrl_impl::set_tx_lo_freq( - double freq, - const std::string &name, - const size_t chan -) { - UHD_LOG_TRACE(unique_id(), "Setting tx lo frequency for " <<name << " with freq = " <<freq); - std::string source = this->get_tx_lo_source(name,chan); + double freq, const std::string& name, const size_t chan) +{ + UHD_LOG_TRACE( + unique_id(), "Setting tx lo frequency for " << name << " with freq = " << freq); + std::string source = this->get_tx_lo_source(name, chan); const double return_freq = this->_set_tx_lo_freq(source, name, freq, chan); this->_update_freq(chan, TX_DIRECTION); this->_update_gain(chan, TX_DIRECTION); @@ -733,61 +666,56 @@ double magnesium_radio_ctrl_impl::set_tx_lo_freq( } double magnesium_radio_ctrl_impl::get_tx_lo_freq( - const std::string & name, - const size_t chan -) { - UHD_LOG_TRACE(unique_id(),"Getting tx lo frequency for " <<name); - std::string source = this->get_tx_lo_source(name,chan); - if(name == MAGNESIUM_LO1){ + const std::string& name, const size_t chan) +{ + UHD_LOG_TRACE(unique_id(), "Getting tx lo frequency for " << name); + std::string source = this->get_tx_lo_source(name, chan); + if (name == MAGNESIUM_LO1) { return _ad9371_freq[TX_DIRECTION]; - }else if (name == MAGNESIUM_LO2){ + } else if (name == MAGNESIUM_LO2) { return _adf4351_freq[TX_DIRECTION]; - }else { - UHD_LOG_ERROR(unique_id(), "There's no LO with this name of "<<name << " in the system."); + } else { + UHD_LOG_ERROR( + unique_id(), "There's no LO with this name of " << name << " in the system."); }; UHD_THROW_INVALID_CODE_PATH(); } - size_t magnesium_radio_ctrl_impl::get_chan_from_dboard_fe( - const std::string &fe, const direction_t /* dir */ -) { + const std::string& fe, const direction_t /* dir */ +) +{ return boost::lexical_cast<size_t>(fe); } std::string magnesium_radio_ctrl_impl::get_dboard_fe_from_chan( - const size_t chan, - const direction_t /* dir */ -) { + const size_t chan, const direction_t /* dir */ +) +{ return std::to_string(chan); } void magnesium_radio_ctrl_impl::set_rpc_client( - uhd::rpc_client::sptr rpcc, - const uhd::device_addr_t &block_args -) { - _rpcc = rpcc; + uhd::rpc_client::sptr rpcc, const uhd::device_addr_t& block_args) +{ + _rpcc = rpcc; _block_args = block_args; UHD_LOG_TRACE(unique_id(), "Instantiating AD9371 control object..."); _ad9371 = magnesium_ad9371_iface::uptr( - new magnesium_ad9371_iface( - _rpcc, - (_radio_slot == "A") ? 0 : 1 - ) - ); + new magnesium_ad9371_iface(_rpcc, (_radio_slot == "A") ? 0 : 1)); if (block_args.has_key("identify")) { const std::string identify_val = block_args.get("identify"); - int identify_duration = std::atoi(identify_val.c_str()); + int identify_duration = std::atoi(identify_val.c_str()); if (identify_duration == 0) { identify_duration = 5; } UHD_LOG_INFO(unique_id(), "Running LED identification process for " << identify_duration - << " seconds."); + << " seconds."); _identify_with_leds(identify_duration); } @@ -795,68 +723,60 @@ void magnesium_radio_ctrl_impl::set_rpc_client( // in arguments from the device args. So if block_args contains a // master_clock_rate key, then it should better be whatever the device is // configured to do. - _master_clock_rate = _rpcc->request_with_token<double>( - _rpc_prefix + "get_master_clock_rate"); + _master_clock_rate = + _rpcc->request_with_token<double>(_rpc_prefix + "get_master_clock_rate"); if (block_args.cast<double>("master_clock_rate", _master_clock_rate) - != _master_clock_rate) { + != _master_clock_rate) { throw uhd::runtime_error(str( boost::format("Master clock rate mismatch. Device returns %f MHz, " "but should have been %f MHz.") % (_master_clock_rate / 1e6) - % (block_args.cast<double>( - "master_clock_rate", _master_clock_rate) / 1e6) - )); + % (block_args.cast<double>("master_clock_rate", _master_clock_rate) / 1e6))); } - UHD_LOG_DEBUG(unique_id(), - "Master Clock Rate is: " << (_master_clock_rate / 1e6) << " MHz."); + UHD_LOG_DEBUG( + unique_id(), "Master Clock Rate is: " << (_master_clock_rate / 1e6) << " MHz."); radio_ctrl_impl::set_rate(_master_clock_rate); // EEPROM paths subject to change FIXME const size_t db_idx = get_block_id().get_block_count(); _tree->access<eeprom_map_t>(_root_path / "eeprom") - .add_coerced_subscriber([this, db_idx](const eeprom_map_t& db_eeprom){ + .add_coerced_subscriber([this, db_idx](const eeprom_map_t& db_eeprom) { this->_rpcc->notify_with_token("set_db_eeprom", db_idx, db_eeprom); }) - .set_publisher([this, db_idx](){ - return this->_rpcc->request_with_token<eeprom_map_t>( - "get_db_eeprom", db_idx - ); - }) - ; + .set_publisher([this, db_idx]() { + return this->_rpcc->request_with_token<eeprom_map_t>("get_db_eeprom", db_idx); + }); // Init sensors - for (const auto &dir : std::vector<direction_t>{RX_DIRECTION, TX_DIRECTION}) { + for (const auto& dir : std::vector<direction_t>{RX_DIRECTION, TX_DIRECTION}) { for (size_t chan_idx = 0; chan_idx < MAGNESIUM_NUM_CHANS; chan_idx++) { _init_mpm_sensors(dir, chan_idx); } } } -bool magnesium_radio_ctrl_impl::get_lo_lock_status( - const direction_t dir -) { - if (not (bool(_rpcc))) { - UHD_LOG_DEBUG(unique_id(), - "Reported no LO lock due to lack of RPC connection."); +bool magnesium_radio_ctrl_impl::get_lo_lock_status(const direction_t dir) +{ + if (not(bool(_rpcc))) { + UHD_LOG_DEBUG(unique_id(), "Reported no LO lock due to lack of RPC connection."); return false; } const std::string trx = (dir == RX_DIRECTION) ? "rx" : "tx"; - const size_t chan = 0; // They're the same after all - const double freq = (dir == RX_DIRECTION) ? - get_rx_frequency(chan) : - get_tx_frequency(chan); + const size_t chan = 0; // They're the same after all + const double freq = (dir == RX_DIRECTION) ? get_rx_frequency(chan) + : get_tx_frequency(chan); - bool lo_lock = _rpcc->request_with_token<bool>( - _rpc_prefix + "get_ad9371_lo_lock", trx); + bool lo_lock = + _rpcc->request_with_token<bool>(_rpc_prefix + "get_ad9371_lo_lock", trx); UHD_LOG_TRACE(unique_id(), "AD9371 " << trx << " LO reports lock: " << (lo_lock ? "Yes" : "No")); if (lo_lock and _map_freq_to_rx_band(freq) == rx_band::LOWBAND) { - lo_lock = lo_lock && _rpcc->request_with_token<bool>( - _rpc_prefix + "get_lowband_lo_lock", trx); + lo_lock = + lo_lock + && _rpcc->request_with_token<bool>(_rpc_prefix + "get_lowband_lo_lock", trx); UHD_LOG_TRACE(unique_id(), - "ADF4351 " << trx << " LO reports lock: " - << (lo_lock ? "Yes" : "No")); + "ADF4351 " << trx << " LO reports lock: " << (lo_lock ? "Yes" : "No")); } return lo_lock; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp index 3d35206ed..dcadb5dea 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -11,20 +11,19 @@ #ifndef INCLUDED_LIBUHD_RFNOC_MAGNESIUM_RADIO_CTRL_IMPL_HPP #define INCLUDED_LIBUHD_RFNOC_MAGNESIUM_RADIO_CTRL_IMPL_HPP +#include "magnesium_ad9371_iface.hpp" #include "magnesium_cpld_ctrl.hpp" #include "magnesium_cpld_regs.hpp" -#include "magnesium_ad9371_iface.hpp" #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <uhdlib/usrp/cores/gpio_atr_3000.hpp> -#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> #include <uhdlib/rfnoc/radio_ctrl_impl.hpp> +#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> #include <uhdlib/usrp/common/adf435x.hpp> +#include <uhdlib/usrp/cores/gpio_atr_3000.hpp> #include <mutex> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief RFNoC block / daughterboard driver for a "Magnesium" daughterboard. * @@ -49,14 +48,7 @@ public: }; //! Frequency bands for TX. Bands are a function of the analog filter banks - enum class tx_band { - INVALID_BAND, - LOWBAND, - BAND0, - BAND1, - BAND2, - BAND3 - }; + enum class tx_band { INVALID_BAND, LOWBAND, BAND0, BAND1, BAND2, BAND3 }; /************************************************************************ * Structors @@ -71,8 +63,8 @@ public: // not reimplemented here double set_rate(double rate); - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); @@ -84,90 +76,59 @@ public: // RX LO std::vector<std::string> get_rx_lo_names(const size_t chan); std::vector<std::string> get_rx_lo_sources( - const std::string &name, - const size_t chan - ); - freq_range_t get_rx_lo_freq_range( - const std::string &name, - const size_t chan - ); + const std::string& name, const size_t chan); + freq_range_t get_rx_lo_freq_range(const std::string& name, const size_t chan); void set_rx_lo_source( - const std::string &src, - const std::string &name, - const size_t chan - ); - const std::string get_rx_lo_source( - const std::string &name, - const size_t chan - ); - - double set_rx_lo_freq( - double freq, - const std::string &name, - const size_t chan - ); - double get_rx_lo_freq(const std::string &name, const size_t chan); + const std::string& src, const std::string& name, const size_t chan); + const std::string get_rx_lo_source(const std::string& name, const size_t chan); + + double set_rx_lo_freq(double freq, const std::string& name, const size_t chan); + double get_rx_lo_freq(const std::string& name, const size_t chan); // TX LO std::vector<std::string> get_tx_lo_names(const size_t chan); std::vector<std::string> get_tx_lo_sources( - const std::string &name, - const size_t chan - ); - freq_range_t get_tx_lo_freq_range( - const std::string &name, - const size_t chan - ); + const std::string& name, const size_t chan); + freq_range_t get_tx_lo_freq_range(const std::string& name, const size_t chan); void set_tx_lo_source( - const std::string &src, - const std::string &name, - const size_t chan - ); - const std::string get_tx_lo_source( - const std::string &name, - const size_t chan - ); - - double set_tx_lo_freq( - double freq, - const std::string &name, - const size_t chan - ); - double get_tx_lo_freq(const std::string &name, const size_t chan); + const std::string& src, const std::string& name, const size_t chan); + const std::string get_tx_lo_source(const std::string& name, const size_t chan); + + double set_tx_lo_freq(double freq, const std::string& name, const size_t chan); + double get_tx_lo_freq(const std::string& name, const size_t chan); // gain double set_tx_gain(const double gain, const size_t chan); double set_rx_gain(const double gain, const size_t chan); - void set_tx_gain_source(const std::string& src, const std::string& name, const size_t chan); + void set_tx_gain_source( + const std::string& src, const std::string& name, const size_t chan); std::string get_tx_gain_source(const std::string& name, const size_t chan); - void set_rx_gain_source(const std::string& src, const std::string& name, const size_t chan); + void set_rx_gain_source( + const std::string& src, const std::string& name, const size_t chan); std::string get_rx_gain_source(const std::string& name, const size_t chan); - size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir); + size_t get_chan_from_dboard_fe(const std::string& fe, const direction_t dir); std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir); - void set_rpc_client( - uhd::rpc_client::sptr rpcc, - const uhd::device_addr_t &block_args - ); + void set_rpc_client(uhd::rpc_client::sptr rpcc, const uhd::device_addr_t& block_args); private: /************************************************************************** * Helpers *************************************************************************/ //! Set tx gain on each gain element - double _set_tx_gain(const std::string &name, const double gain, const size_t chan); + double _set_tx_gain(const std::string& name, const double gain, const size_t chan); //! Set rx gain on each gain element - double _set_rx_gain(const std::string &name, const double gain, const size_t chan); + double _set_rx_gain(const std::string& name, const double gain, const size_t chan); //! Get tx gain on each gain element - double _get_tx_gain(const std::string &name, const size_t chan); + double _get_tx_gain(const std::string& name, const size_t chan); //! Get rx gain on each gain element - double _get_rx_gain(const std::string &name, const size_t chan); + double _get_rx_gain(const std::string& name, const size_t chan); //! Initialize all the peripherals connected to this block void _init_peripherals(); @@ -176,18 +137,12 @@ private: void _init_defaults(); //! Init a subtree for the RF frontends - void _init_frontend_subtree( - uhd::property_tree::sptr subtree, - const size_t chan_idx - ); + void _init_frontend_subtree(uhd::property_tree::sptr subtree, const size_t chan_idx); //! Initialize property tree void _init_prop_tree(); - void _init_mpm_sensors( - const direction_t dir, - const size_t chan_idx - ); + void _init_mpm_sensors(const direction_t dir, const size_t chan_idx); //! Map a frequency in Hz to an rx_band value. Will return // rx_band::INVALID_BAND if the frequency is out of range. @@ -201,92 +156,57 @@ private: *************************************************************************/ //! Return LO lock status. Factors in current band (low/high) and // direction (TX/RX) - bool get_lo_lock_status( - const direction_t dir - ); + bool get_lo_lock_status(const direction_t dir); /************************************************************************** * Gain Controls (implemented in magnesium_radio_ctrl_gain.cpp) *************************************************************************/ //! Set the attenuation of the DSA - double _dsa_set_att( - const double att, - const size_t chan, - const direction_t dir - ); + double _dsa_set_att(const double att, const size_t chan, const direction_t dir); - double _dsa_get_att( - const size_t chan, - const direction_t dir - ); + double _dsa_get_att(const size_t chan, const direction_t dir); //! Write the DSA word - void _set_dsa_val( - const size_t chan, - const direction_t dir, - const uint32_t dsa_val - ); + void _set_dsa_val(const size_t chan, const direction_t dir, const uint32_t dsa_val); double _set_all_gain( - const double gain, - const double freq, - const size_t chan, - const direction_t dir - ); + const double gain, const double freq, const size_t chan, const direction_t dir); - double _get_all_gain( - const size_t chan, - const direction_t dir - ); + double _get_all_gain(const size_t chan, const direction_t dir); void _update_gain(const size_t chan, direction_t dir); - void _update_freq( - const size_t chan, - const uhd::direction_t dir - ); + void _update_freq(const size_t chan, const uhd::direction_t dir); /************************************************************************** * CPLD Controls (implemented in magnesium_radio_ctrl_cpld.cpp) *************************************************************************/ //! Blink the front-panel LEDs for \p identify_duration, then reset CPLD // and resume normal operation. - void _identify_with_leds( - const int identify_duration - ); + void _identify_with_leds(const int identify_duration); - void _update_rx_freq_switches( - const double freq, + void _update_rx_freq_switches(const double freq, const bool bypass_lnas, - const magnesium_cpld_ctrl::chan_sel_t chan_sel - ); + const magnesium_cpld_ctrl::chan_sel_t chan_sel); - void _update_tx_freq_switches( - const double freq, + void _update_tx_freq_switches(const double freq, const bool bypass_amps, - const magnesium_cpld_ctrl::chan_sel_t chan_sel - ); + const magnesium_cpld_ctrl::chan_sel_t chan_sel); - void _update_atr_switches( - const magnesium_cpld_ctrl::chan_sel_t chan, + void _update_atr_switches(const magnesium_cpld_ctrl::chan_sel_t chan, const direction_t dir, - const std::string &ant - ); + const std::string& ant); - double _set_rx_lo_freq( - const std::string source, + double _set_rx_lo_freq(const std::string source, const std::string name, const double freq, - const size_t chan - ); + const size_t chan); - double _set_tx_lo_freq( - const std::string source, + double _set_tx_lo_freq(const std::string source, const std::string name, const double freq, - const size_t chan - ); + const size_t chan); /************************************************************************** * Private attributes *************************************************************************/ @@ -334,30 +254,37 @@ private: //! Sampling rate, and also ref clock frequency for the lowband LOs. double _master_clock_rate = 1.0; - //! Desired RF frequency - std::map<direction_t,double> _desired_rf_freq = { {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9} }; + //! Desired RF frequency + std::map<direction_t, double> _desired_rf_freq = { + {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9}}; //! Coerced adf4351 frequency //! Coerced ad9371 frequency - std::map<direction_t,double> _ad9371_freq = { {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9} }; + std::map<direction_t, double> _ad9371_freq = { + {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9}}; //! Coerced adf4351 frequency - std::map<direction_t,double> _adf4351_freq = { {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9} }; + std::map<direction_t, double> _adf4351_freq = { + {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9}}; //! Low band enable - std::map<direction_t,bool> _is_low_band = { {RX_DIRECTION, false}, {TX_DIRECTION, false} }; + std::map<direction_t, bool> _is_low_band = { + {RX_DIRECTION, false}, {TX_DIRECTION, false}}; //! AD9371 gain - double _ad9371_rx_gain = 0.0; - double _ad9371_tx_gain = 0.0; - std::map<direction_t,double> _ad9371_att = { {RX_DIRECTION, 0.0}, {TX_DIRECTION, 0.0} }; + double _ad9371_rx_gain = 0.0; + double _ad9371_tx_gain = 0.0; + std::map<direction_t, double> _ad9371_att = { + {RX_DIRECTION, 0.0}, {TX_DIRECTION, 0.0}}; //! DSA attenuation - double _dsa_rx_att = 0.0; - double _dsa_tx_att = 0.0; - std::map<direction_t,double> _dsa_att = { {RX_DIRECTION, 0.0}, {TX_DIRECTION, 0.0} }; + double _dsa_rx_att = 0.0; + double _dsa_tx_att = 0.0; + std::map<direction_t, double> _dsa_att = {{RX_DIRECTION, 0.0}, {TX_DIRECTION, 0.0}}; //! amp gain - std::map<direction_t,bool> _amp_bypass = { {RX_DIRECTION, true}, {TX_DIRECTION, true} }; + std::map<direction_t, bool> _amp_bypass = { + {RX_DIRECTION, true}, {TX_DIRECTION, true}}; //! All gain double _all_rx_gain = 0.0; double _all_tx_gain = 0.0; //! Gain profile - std::map<direction_t,std::string> _gain_profile = { {RX_DIRECTION, "default"}, {TX_DIRECTION, "default"} }; + std::map<direction_t, std::string> _gain_profile = { + {RX_DIRECTION, "default"}, {TX_DIRECTION, "default"}}; bool _rx_bypass_lnas = true; bool _tx_bypass_amp = true; @@ -367,11 +294,11 @@ private: {magnesium_cpld_ctrl::CHAN1, magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1}, {magnesium_cpld_ctrl::CHAN2, - magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1} - }; + magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1}}; //! RX LO SOURCE - // NOTE for magnesium only ad9371 LO that can be connected to the external LO so we only need one var here + // NOTE for magnesium only ad9371 LO that can be connected to the external LO so we + // only need one var here std::string _rx_lo_source = "internal"; }; /* class radio_ctrl_impl */ @@ -379,4 +306,3 @@ private: }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_RFNOC_MAGNESIUM_RADIO_CTRL_IMPL_HPP */ - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp index 901bb1474..422b07ebb 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp @@ -4,40 +4,32 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "magnesium_radio_ctrl_impl.hpp" #include "magnesium_constants.hpp" -#include <uhd/utils/log.hpp> +#include "magnesium_radio_ctrl_impl.hpp" +#include <uhd/transport/chdr.hpp> #include <uhd/types/eeprom.hpp> #include <uhd/types/sensors.hpp> -#include <uhd/transport/chdr.hpp> +#include <uhd/utils/log.hpp> #include <uhdlib/usrp/cores/spi_core_3000.hpp> -#include <vector> -#include <string> #include <boost/algorithm/string.hpp> -#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/case_conv.hpp> +#include <boost/algorithm/string/split.hpp> +#include <string> +#include <vector> using namespace uhd; using namespace uhd::rfnoc; namespace { - enum slave_select_t { - SEN_CPLD = 1, - SEN_TX_LO = 2, - SEN_RX_LO = 4, - SEN_PHASE_DAC = 8 - }; - - constexpr double MAGNESIUM_DEFAULT_FREQ = 2.5e9; // Hz - constexpr double MAGNESIUM_DEFAULT_BANDWIDTH = 100e6; // Hz - constexpr char MAGNESIUM_DEFAULT_RX_ANTENNA[] = "RX2"; - constexpr char MAGNESIUM_DEFAULT_TX_ANTENNA[] = "TX/RX"; - - //! Magnesium gain profile options - const std::vector<std::string> MAGNESIUM_GP_OPTIONS = { - "manual", - "default" - }; -} +enum slave_select_t { SEN_CPLD = 1, SEN_TX_LO = 2, SEN_RX_LO = 4, SEN_PHASE_DAC = 8 }; + +constexpr double MAGNESIUM_DEFAULT_FREQ = 2.5e9; // Hz +constexpr double MAGNESIUM_DEFAULT_BANDWIDTH = 100e6; // Hz +constexpr char MAGNESIUM_DEFAULT_RX_ANTENNA[] = "RX2"; +constexpr char MAGNESIUM_DEFAULT_TX_ANTENNA[] = "TX/RX"; + +//! Magnesium gain profile options +const std::vector<std::string> MAGNESIUM_GP_OPTIONS = {"manual", "default"}; +} // namespace //! Helper function to extract single value of port number. // @@ -45,32 +37,34 @@ namespace { // This function convert the format of attribute "Radio_N_M" // to a single value port number = N*number_of_port_per_radio + M -uint32_t extract_port_number(std::string radio_src_string, uhd::property_tree::sptr ptree){ +uint32_t extract_port_number(std::string radio_src_string, uhd::property_tree::sptr ptree) +{ std::string s_val = "0"; std::vector<std::string> radio_strings; - boost::algorithm::split( - radio_strings, + boost::algorithm::split(radio_strings, radio_src_string, boost::is_any_of("_/"), boost::token_compress_on); boost::to_lower(radio_strings[0]); - if (radio_strings.size()<3) { - throw uhd::runtime_error(str(boost::format("%s is an invalid GPIO source string.") % radio_src_string)); + if (radio_strings.size() < 3) { + throw uhd::runtime_error(str( + boost::format("%s is an invalid GPIO source string.") % radio_src_string)); } size_t radio_num = std::stoi(radio_strings[1]); - size_t port_num = std::stoi(radio_strings[2]); + size_t port_num = std::stoi(radio_strings[2]); if (radio_strings[0] != "radio") { - throw uhd::runtime_error("Front panel GPIO bank can only accept a radio block as its driver."); + throw uhd::runtime_error( + "Front panel GPIO bank can only accept a radio block as its driver."); } - std::string radio_port_out = "Radio_"+ radio_strings[1] + "/ports/out"; - std::string radio_port_path = radio_port_out + "/"+ radio_strings[2]; - auto found = ptree->exists(fs_path("xbar")/ radio_port_path); - if (not found){ - throw uhd::runtime_error(str(boost::format( - "Could not find radio port %s.\n") % radio_port_path)); + std::string radio_port_out = "Radio_" + radio_strings[1] + "/ports/out"; + std::string radio_port_path = radio_port_out + "/" + radio_strings[2]; + auto found = ptree->exists(fs_path("xbar") / radio_port_path); + if (not found) { + throw uhd::runtime_error( + str(boost::format("Could not find radio port %s.\n") % radio_port_path)); } - size_t port_size = ptree->list(fs_path("xbar")/ radio_port_out).size(); - return radio_num*port_size + port_num; + size_t port_size = ptree->list(fs_path("xbar") / radio_port_out).size(); + return radio_num * port_size + port_num; } void magnesium_radio_ctrl_impl::_init_defaults() @@ -80,8 +74,7 @@ void magnesium_radio_ctrl_impl::_init_defaults() const size_t num_tx_chans = get_input_ports().size(); UHD_LOG_TRACE(unique_id(), - "Num TX chans: " << num_tx_chans - << " Num RX chans: " << num_rx_chans); + "Num TX chans: " << num_tx_chans << " Num RX chans: " << num_rx_chans); for (size_t chan = 0; chan < num_rx_chans; chan++) { radio_ctrl_impl::set_rx_frequency(MAGNESIUM_DEFAULT_FREQ, chan); @@ -104,8 +97,7 @@ void magnesium_radio_ctrl_impl::_init_defaults() const size_t default_spp = (_tree->access<size_t>("mtu/recv").get() - max_bytes_header) / (2 * sizeof(int16_t)); - UHD_LOG_DEBUG(unique_id(), - "Setting default spp to " << default_spp); + UHD_LOG_DEBUG(unique_id(), "Setting default spp to " << default_spp); _tree->access<int>(get_arg_path("spp") / "value").set(default_spp); } @@ -113,606 +105,453 @@ void magnesium_radio_ctrl_impl::_init_peripherals() { UHD_LOG_TRACE(unique_id(), "Initializing peripherals..."); UHD_LOG_TRACE(unique_id(), "Initializing SPI core..."); - _spi = spi_core_3000::make(_get_ctrl(0), - regs::sr_addr(regs::SPI), - regs::rb_addr(regs::RB_SPI) - ); + _spi = spi_core_3000::make( + _get_ctrl(0), regs::sr_addr(regs::SPI), regs::rb_addr(regs::RB_SPI)); UHD_LOG_TRACE(unique_id(), "Initializing CPLD..."); UHD_LOG_TRACE(unique_id(), "Creating new CPLD object..."); spi_config_t spi_config; spi_config.use_custom_divider = true; - spi_config.divider = 125; - spi_config.mosi_edge = spi_config_t::EDGE_RISE; - spi_config.miso_edge = spi_config_t::EDGE_FALL; + spi_config.divider = 125; + spi_config.mosi_edge = spi_config_t::EDGE_RISE; + spi_config.miso_edge = spi_config_t::EDGE_FALL; UHD_LOG_TRACE(unique_id(), "Making CPLD object..."); _cpld = std::make_shared<magnesium_cpld_ctrl>( - [this, spi_config](const uint32_t transaction){ // Write functor - this->_spi->write_spi( - SEN_CPLD, - spi_config, - transaction, - 24 - ); + [this, spi_config](const uint32_t transaction) { // Write functor + this->_spi->write_spi(SEN_CPLD, spi_config, transaction, 24); }, - [this, spi_config](const uint32_t transaction){ // Read functor - return this->_spi->read_spi( - SEN_CPLD, - spi_config, - transaction, - 24 - ); - } - ); + [this, spi_config](const uint32_t transaction) { // Read functor + return this->_spi->read_spi(SEN_CPLD, spi_config, transaction, 24); + }); _update_atr_switches( - magnesium_cpld_ctrl::BOTH, - DX_DIRECTION, - radio_ctrl_impl::get_rx_antenna(0) - ); + magnesium_cpld_ctrl::BOTH, DX_DIRECTION, radio_ctrl_impl::get_rx_antenna(0)); UHD_LOG_TRACE(unique_id(), "Initializing TX LO..."); - _tx_lo = adf435x_iface::make_adf4351( - [this](const std::vector<uint32_t> transactions){ - for (const uint32_t transaction: transactions) { - this->_spi->write_spi( - SEN_TX_LO, - spi_config_t::EDGE_RISE, - transaction, - 32 - ); - } + _tx_lo = adf435x_iface::make_adf4351([this]( + const std::vector<uint32_t> transactions) { + for (const uint32_t transaction : transactions) { + this->_spi->write_spi(SEN_TX_LO, spi_config_t::EDGE_RISE, transaction, 32); } - ); + }); UHD_LOG_TRACE(unique_id(), "Initializing RX LO..."); - _rx_lo = adf435x_iface::make_adf4351( - [this](const std::vector<uint32_t> transactions){ - for (const uint32_t transaction: transactions) { - this->_spi->write_spi( - SEN_RX_LO, - spi_config_t::EDGE_RISE, - transaction, - 32 - ); - } + _rx_lo = adf435x_iface::make_adf4351([this]( + const std::vector<uint32_t> transactions) { + for (const uint32_t transaction : transactions) { + this->_spi->write_spi(SEN_RX_LO, spi_config_t::EDGE_RISE, transaction, 32); } - ); + }); _gpio.clear(); // Following the as-if rule, this can get optimized out for (size_t radio_idx = 0; radio_idx < _get_num_radios(); radio_idx++) { - UHD_LOG_TRACE(unique_id(), - "Initializing GPIOs for channel " << radio_idx); - _gpio.emplace_back( - usrp::gpio_atr::gpio_atr_3000::make( - _get_ctrl(radio_idx), - regs::sr_addr(regs::GPIO), - regs::rb_addr(regs::RB_DB_GPIO) - ) - ); + UHD_LOG_TRACE(unique_id(), "Initializing GPIOs for channel " << radio_idx); + _gpio.emplace_back(usrp::gpio_atr::gpio_atr_3000::make(_get_ctrl(radio_idx), + regs::sr_addr(regs::GPIO), + regs::rb_addr(regs::RB_DB_GPIO))); // DSA and AD9371 gain bits do *not* toggle on ATR modes. If we ever // connect anything else to this core, we might need to set_atr_mode() // to MODE_ATR on those bits. For now, all bits simply do what they're // told, and don't toggle on RX/TX state changes. - _gpio.back()->set_atr_mode( - usrp::gpio_atr::MODE_GPIO, // Disable ATR mode - usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL - ); - _gpio.back()->set_gpio_ddr( - usrp::gpio_atr::DDR_OUTPUT, // Make all GPIOs outputs - usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL - ); + _gpio.back()->set_atr_mode(usrp::gpio_atr::MODE_GPIO, // Disable ATR mode + usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); + _gpio.back()->set_gpio_ddr(usrp::gpio_atr::DDR_OUTPUT, // Make all GPIOs outputs + usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); } UHD_LOG_TRACE(unique_id(), "Initializing front-panel GPIO control...") _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make( - _get_ctrl(0), - regs::sr_addr(regs::FP_GPIO), - regs::rb_addr(regs::RB_FP_GPIO) - ); + _get_ctrl(0), regs::sr_addr(regs::FP_GPIO), regs::rb_addr(regs::RB_FP_GPIO)); } void magnesium_radio_ctrl_impl::_init_frontend_subtree( - uhd::property_tree::sptr subtree, - const size_t chan_idx -) { + uhd::property_tree::sptr subtree, const size_t chan_idx) +{ const fs_path tx_fe_path = fs_path("tx_frontends") / chan_idx; const fs_path rx_fe_path = fs_path("rx_frontends") / chan_idx; UHD_LOG_TRACE(unique_id(), - "Adding non-RFNoC block properties for channel " << chan_idx << - " to prop tree path " << tx_fe_path << " and " << rx_fe_path); + "Adding non-RFNoC block properties for channel " + << chan_idx << " to prop tree path " << tx_fe_path << " and " << rx_fe_path); // TX Standard attributes subtree->create<std::string>(tx_fe_path / "name") - .set(str(boost::format("Magnesium"))) - ; - subtree->create<std::string>(tx_fe_path / "connection") - .set("IQ") - ; + .set(str(boost::format("Magnesium"))); + subtree->create<std::string>(tx_fe_path / "connection").set("IQ"); // RX Standard attributes subtree->create<std::string>(rx_fe_path / "name") - .set(str(boost::format("Magnesium"))) - ; - subtree->create<std::string>(rx_fe_path / "connection") - .set("IQ") - ; + .set(str(boost::format("Magnesium"))); + subtree->create<std::string>(rx_fe_path / "connection").set("IQ"); // TX Antenna subtree->create<std::string>(tx_fe_path / "antenna" / "value") - .add_coerced_subscriber([this, chan_idx](const std::string &ant){ + .add_coerced_subscriber([this, chan_idx](const std::string& ant) { this->set_tx_antenna(ant, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_tx_antenna(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_tx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(tx_fe_path / "antenna" / "options") .set({MAGNESIUM_DEFAULT_TX_ANTENNA}) - .add_coerced_subscriber([](const std::vector<std::string> &){ - throw uhd::runtime_error( - "Attempting to update antenna options!"); - }) - ; + .add_coerced_subscriber([](const std::vector<std::string>&) { + throw uhd::runtime_error("Attempting to update antenna options!"); + }); // RX Antenna subtree->create<std::string>(rx_fe_path / "antenna" / "value") - .add_coerced_subscriber([this, chan_idx](const std::string &ant){ + .add_coerced_subscriber([this, chan_idx](const std::string& ant) { this->set_rx_antenna(ant, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_rx_antenna(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_rx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(rx_fe_path / "antenna" / "options") .set(MAGNESIUM_RX_ANTENNAS) - .add_coerced_subscriber([](const std::vector<std::string> &){ - throw uhd::runtime_error( - "Attempting to update antenna options!"); - }) - ; + .add_coerced_subscriber([](const std::vector<std::string>&) { + throw uhd::runtime_error("Attempting to update antenna options!"); + }); // TX frequency subtree->create<double>(tx_fe_path / "freq" / "value") - .set_coercer([this, chan_idx](const double freq){ + .set_coercer([this, chan_idx](const double freq) { return this->set_tx_frequency(freq, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_tx_frequency(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_tx_frequency(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "freq" / "range") .set(meta_range_t(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ, 1.0)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update freq range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update freq range!"); + }); // RX frequency subtree->create<double>(rx_fe_path / "freq" / "value") - .set_coercer([this, chan_idx](const double freq){ + .set_coercer([this, chan_idx](const double freq) { return this->set_rx_frequency(freq, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_rx_frequency(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_rx_frequency(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "freq" / "range") .set(meta_range_t(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ, 1.0)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update freq range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update freq range!"); + }); // TX bandwidth subtree->create<double>(tx_fe_path / "bandwidth" / "value") .set(AD9371_TX_MAX_BANDWIDTH) - .set_coercer([this, chan_idx](const double bw){ + .set_coercer([this, chan_idx](const double bw) { return this->set_tx_bandwidth(bw, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_tx_bandwidth(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_tx_bandwidth(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "bandwidth" / "range") .set(meta_range_t(AD9371_TX_MIN_BANDWIDTH, AD9371_TX_MAX_BANDWIDTH)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update bandwidth range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update bandwidth range!"); + }); // RX bandwidth subtree->create<double>(rx_fe_path / "bandwidth" / "value") .set(AD9371_RX_MAX_BANDWIDTH) - .set_coercer([this, chan_idx](const double bw){ + .set_coercer([this, chan_idx](const double bw) { return this->set_rx_bandwidth(bw, chan_idx); - }) - ; + }); subtree->create<meta_range_t>(rx_fe_path / "bandwidth" / "range") .set(meta_range_t(AD9371_RX_MIN_BANDWIDTH, AD9371_RX_MAX_BANDWIDTH)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update bandwidth range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update bandwidth range!"); + }); // TX gains subtree->create<double>(tx_fe_path / "gains" / "all" / "value") - .set_coercer([this, chan_idx](const double gain){ - return this->set_tx_gain(gain, chan_idx); - }) - .set_publisher([this, chan_idx](){ - return radio_ctrl_impl::get_tx_gain(chan_idx); - }) - ; + .set_coercer([this, chan_idx]( + const double gain) { return this->set_tx_gain(gain, chan_idx); }) + .set_publisher( + [this, chan_idx]() { return radio_ctrl_impl::get_tx_gain(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "gains" / "all" / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[TX_DIRECTION] == "manual") { return meta_range_t(0.0, 0.0, 0.0); } else { - return meta_range_t( - ALL_TX_MIN_GAIN, - ALL_TX_MAX_GAIN, - ALL_TX_GAIN_STEP - ); + return meta_range_t(ALL_TX_MIN_GAIN, ALL_TX_MAX_GAIN, ALL_TX_GAIN_STEP); } - }) - ; + }); subtree->create<std::vector<std::string>>(tx_fe_path / "gains/all/profile/options") .set({"manual", "default"}); subtree->create<std::string>(tx_fe_path / "gains/all/profile/value") - .set_coercer([this](const std::string& profile){ + .set_coercer([this](const std::string& profile) { std::string return_profile = profile; - if (std::find(MAGNESIUM_GP_OPTIONS.begin(), - MAGNESIUM_GP_OPTIONS.end(), - profile - ) == MAGNESIUM_GP_OPTIONS.end()) - { + if (std::find( + MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) + == MAGNESIUM_GP_OPTIONS.end()) { return_profile = "default"; } _gain_profile[TX_DIRECTION] = return_profile; return return_profile; }) - .set_publisher([this](){ - return _gain_profile[TX_DIRECTION]; - }) - ; + .set_publisher([this]() { return _gain_profile[TX_DIRECTION]; }); // RX gains subtree->create<double>(rx_fe_path / "gains" / "all" / "value") - .set_coercer([this, chan_idx](const double gain){ - return this->set_rx_gain(gain, chan_idx); - }) - .set_publisher([this, chan_idx](){ - return radio_ctrl_impl::get_rx_gain(chan_idx); - }) - ; + .set_coercer([this, chan_idx]( + const double gain) { return this->set_rx_gain(gain, chan_idx); }) + .set_publisher( + [this, chan_idx]() { return radio_ctrl_impl::get_rx_gain(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "gains" / "all" / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[RX_DIRECTION] == "manual") { return meta_range_t(0.0, 0.0, 0.0); } else { - return meta_range_t( - ALL_RX_MIN_GAIN, - ALL_RX_MAX_GAIN, - ALL_RX_GAIN_STEP - ); + return meta_range_t(ALL_RX_MIN_GAIN, ALL_RX_MAX_GAIN, ALL_RX_GAIN_STEP); } - }) - ; + }); - subtree->create<std::vector<std::string> >(rx_fe_path / "gains/all/profile/options") - .set(MAGNESIUM_GP_OPTIONS); + subtree->create<std::vector<std::string>>(rx_fe_path / "gains/all/profile/options") + .set(MAGNESIUM_GP_OPTIONS); subtree->create<std::string>(rx_fe_path / "gains/all/profile/value") - .set_coercer([this](const std::string& profile){ + .set_coercer([this](const std::string& profile) { std::string return_profile = profile; - if (std::find(MAGNESIUM_GP_OPTIONS.begin(), - MAGNESIUM_GP_OPTIONS.end(), - profile - ) == MAGNESIUM_GP_OPTIONS.end()) - { + if (std::find( + MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) + == MAGNESIUM_GP_OPTIONS.end()) { return_profile = "default"; } _gain_profile[RX_DIRECTION] = return_profile; return return_profile; }) - .set_publisher([this](){ - return _gain_profile[RX_DIRECTION]; - }) - ; + .set_publisher([this]() { return _gain_profile[RX_DIRECTION]; }); // TX mykonos attenuation subtree->create<double>(tx_fe_path / "gains" / MAGNESIUM_GAIN1 / "value") - .set_coercer([this, chan_idx](const double gain){ + .set_coercer([this, chan_idx](const double gain) { return _set_tx_gain(MAGNESIUM_GAIN1, gain, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->_get_tx_gain(MAGNESIUM_GAIN1, chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return this->_get_tx_gain(MAGNESIUM_GAIN1, chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "gains" / MAGNESIUM_GAIN1 / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[TX_DIRECTION] == "manual") { return meta_range_t( - AD9371_MIN_TX_GAIN, - AD9371_MAX_TX_GAIN, - AD9371_TX_GAIN_STEP - ); + AD9371_MIN_TX_GAIN, AD9371_MAX_TX_GAIN, AD9371_TX_GAIN_STEP); } else { return meta_range_t(0.0, 0.0, 0.0); } - }) - ; - // TX DSA + }); + // TX DSA subtree->create<double>(tx_fe_path / "gains" / MAGNESIUM_GAIN2 / "value") - .set_coercer([this, chan_idx](const double gain){ + .set_coercer([this, chan_idx](const double gain) { return this->_set_tx_gain(MAGNESIUM_GAIN2, gain, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->_get_tx_gain(MAGNESIUM_GAIN2, chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return this->_get_tx_gain(MAGNESIUM_GAIN2, chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "gains" / MAGNESIUM_GAIN2 / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[TX_DIRECTION] == "manual") { return meta_range_t(DSA_MIN_GAIN, DSA_MAX_GAIN, DSA_GAIN_STEP); - }else{ + } else { return meta_range_t(0.0, 0.0, 0.0); } - }) - ; - //TX amp + }); + // TX amp subtree->create<double>(tx_fe_path / "gains" / MAGNESIUM_AMP / "value") .set_coercer([this, chan_idx](const double gain) { return this->_set_tx_gain(MAGNESIUM_AMP, gain, chan_idx); }) - .set_publisher([this, chan_idx]() { - return this->_get_tx_gain(MAGNESIUM_AMP, chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return this->_get_tx_gain(MAGNESIUM_AMP, chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "gains" / MAGNESIUM_AMP / "range") - .add_coerced_subscriber([](const meta_range_t &) { - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[TX_DIRECTION] == "manual") { return meta_range_t(AMP_MIN_GAIN, AMP_MAX_GAIN, AMP_GAIN_STEP); - }else{ + } else { return meta_range_t(0.0, 0.0, 0.0); } - }) - ; + }); // RX mykonos attenuation subtree->create<double>(rx_fe_path / "gains" / MAGNESIUM_GAIN1 / "value") - .set_coercer([this, chan_idx](const double gain){ - UHD_VAR(gain); + .set_coercer([this, chan_idx](const double gain) { + UHD_VAR(gain); return this->_set_rx_gain(MAGNESIUM_GAIN1, gain, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->_get_rx_gain(MAGNESIUM_GAIN1, chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return this->_get_rx_gain(MAGNESIUM_GAIN1, chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "gains" / MAGNESIUM_GAIN1 / "range") - .add_coerced_subscriber([](const meta_range_t &) { - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[RX_DIRECTION] == "manual") { return meta_range_t( - AD9371_MIN_RX_GAIN, - AD9371_MAX_RX_GAIN, - AD9371_RX_GAIN_STEP - ); + AD9371_MIN_RX_GAIN, AD9371_MAX_RX_GAIN, AD9371_RX_GAIN_STEP); } else { return meta_range_t(0.0, 0.0, 0.0); } - }) - ; - //RX DSA + }); + // RX DSA subtree->create<double>(rx_fe_path / "gains" / MAGNESIUM_GAIN2 / "value") .set_coercer([this, chan_idx](const double gain) { UHD_VAR(gain); return this->_set_rx_gain(MAGNESIUM_GAIN2, gain, chan_idx); }) - .set_publisher([this, chan_idx]() { - return this->_get_rx_gain(MAGNESIUM_GAIN2, chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return this->_get_rx_gain(MAGNESIUM_GAIN2, chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "gains" / MAGNESIUM_GAIN2 / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[RX_DIRECTION] == "manual") { return meta_range_t(DSA_MIN_GAIN, DSA_MAX_GAIN, DSA_MAX_GAIN); - }else{ + } else { return meta_range_t(0.0, 0.0, 0.0); } - }) - ; + }); - //RX amp + // RX amp subtree->create<double>(rx_fe_path / "gains" / MAGNESIUM_AMP / "value") .set_coercer([this, chan_idx](const double gain) { return this->_set_rx_gain(MAGNESIUM_AMP, gain, chan_idx); }) - .set_publisher([this, chan_idx]() { - return this->_get_rx_gain(MAGNESIUM_AMP, chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return this->_get_rx_gain(MAGNESIUM_AMP, chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "gains" / MAGNESIUM_AMP / "range") - .add_coerced_subscriber([](const meta_range_t &) { - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { if (_gain_profile[RX_DIRECTION] == "manual") { return meta_range_t(AMP_MIN_GAIN, AMP_MAX_GAIN, AMP_GAIN_STEP); - }else{ + } else { return meta_range_t(0.0, 0.0, 0.0); } - }) - ; + }); // TX LO lock sensor ////////////////////////////////////////////////////// // Note: The lowband and AD9371 LO lock sensors are generated // programmatically in set_rpc_client(). The actual lo_locked publisher is // also set there. subtree->create<sensor_value_t>(tx_fe_path / "sensors" / "lo_locked") - .set(sensor_value_t("all_los", false, "locked", "unlocked")) - .add_coerced_subscriber([](const sensor_value_t &){ - throw uhd::runtime_error( - "Attempting to write to sensor!"); + .set(sensor_value_t("all_los", false, "locked", "unlocked")) + .add_coerced_subscriber([](const sensor_value_t&) { + throw uhd::runtime_error("Attempting to write to sensor!"); }) - .set_publisher([this](){ + .set_publisher([this]() { return sensor_value_t( - "all_los", - this->get_lo_lock_status(TX_DIRECTION), - "locked", "unlocked" - ); - }) - ; + "all_los", this->get_lo_lock_status(TX_DIRECTION), "locked", "unlocked"); + }); // RX LO lock sensor (see not on TX LO lock sensor) subtree->create<sensor_value_t>(rx_fe_path / "sensors" / "lo_locked") - .set(sensor_value_t("all_los", false, "locked", "unlocked")) - .add_coerced_subscriber([](const sensor_value_t &){ - throw uhd::runtime_error( - "Attempting to write to sensor!"); + .set(sensor_value_t("all_los", false, "locked", "unlocked")) + .add_coerced_subscriber([](const sensor_value_t&) { + throw uhd::runtime_error("Attempting to write to sensor!"); }) - .set_publisher([this](){ + .set_publisher([this]() { return sensor_value_t( - "all_los", - this->get_lo_lock_status(RX_DIRECTION), - "locked", "unlocked" - ); - }) - ; - //LO Specific - //RX LO - subtree->create<meta_range_t>(rx_fe_path / "los"/MAGNESIUM_LO1/"freq/range") - .set_publisher([this,chan_idx](){ + "all_los", this->get_lo_lock_status(RX_DIRECTION), "locked", "unlocked"); + }); + // LO Specific + // RX LO + subtree->create<meta_range_t>(rx_fe_path / "los" / MAGNESIUM_LO1 / "freq/range") + .set_publisher([this, chan_idx]() { return this->get_rx_lo_freq_range(MAGNESIUM_LO1, chan_idx); - }) - ; - subtree->create<std::vector<std::string>>(rx_fe_path / "los"/MAGNESIUM_LO1/"source/options") - .set_publisher([this,chan_idx](){ + }); + subtree + ->create<std::vector<std::string>>( + rx_fe_path / "los" / MAGNESIUM_LO1 / "source/options") + .set_publisher([this, chan_idx]() { return this->get_rx_lo_sources(MAGNESIUM_LO1, chan_idx); + }); + subtree->create<std::string>(rx_fe_path / "los" / MAGNESIUM_LO1 / "source/value") + .add_coerced_subscriber([this, chan_idx](std::string src) { + this->set_rx_lo_source(src, MAGNESIUM_LO1, chan_idx); }) - ; - subtree->create<std::string>(rx_fe_path / "los"/MAGNESIUM_LO1/"source/value") - .add_coerced_subscriber([this,chan_idx](std::string src){ - this->set_rx_lo_source(src, MAGNESIUM_LO1,chan_idx); - }) - .set_publisher([this,chan_idx](){ + .set_publisher([this, chan_idx]() { return this->get_rx_lo_source(MAGNESIUM_LO1, chan_idx); - }) - ; - subtree->create<double>(rx_fe_path / "los"/MAGNESIUM_LO1/"freq/value") - .set_publisher([this,chan_idx](){ - return this->get_rx_lo_freq(MAGNESIUM_LO1, chan_idx); - }) - .set_coercer([this,chan_idx](const double freq){ + }); + subtree->create<double>(rx_fe_path / "los" / MAGNESIUM_LO1 / "freq/value") + .set_publisher( + [this, chan_idx]() { return this->get_rx_lo_freq(MAGNESIUM_LO1, chan_idx); }) + .set_coercer([this, chan_idx](const double freq) { return this->set_rx_lo_freq(freq, MAGNESIUM_LO1, chan_idx); - }) - ; + }); - subtree->create<meta_range_t>(rx_fe_path / "los"/MAGNESIUM_LO2/"freq/range") - .set_publisher([this,chan_idx](){ + subtree->create<meta_range_t>(rx_fe_path / "los" / MAGNESIUM_LO2 / "freq/range") + .set_publisher([this, chan_idx]() { return this->get_rx_lo_freq_range(MAGNESIUM_LO2, chan_idx); - }) - ; - subtree->create<std::vector<std::string>>(rx_fe_path / "los"/MAGNESIUM_LO2/"source/options") - .set_publisher([this,chan_idx](){ + }); + subtree + ->create<std::vector<std::string>>( + rx_fe_path / "los" / MAGNESIUM_LO2 / "source/options") + .set_publisher([this, chan_idx]() { return this->get_rx_lo_sources(MAGNESIUM_LO2, chan_idx); - }) - ; + }); - subtree->create<std::string>(rx_fe_path / "los"/MAGNESIUM_LO2/"source/value") - .add_coerced_subscriber([this,chan_idx](std::string src){ + subtree->create<std::string>(rx_fe_path / "los" / MAGNESIUM_LO2 / "source/value") + .add_coerced_subscriber([this, chan_idx](std::string src) { this->set_rx_lo_source(src, MAGNESIUM_LO2, chan_idx); }) - .set_publisher([this,chan_idx](){ + .set_publisher([this, chan_idx]() { return this->get_rx_lo_source(MAGNESIUM_LO2, chan_idx); - }) - ; - subtree->create<double>(rx_fe_path / "los"/MAGNESIUM_LO2/"freq/value") - .set_publisher([this,chan_idx](){ - return this->get_rx_lo_freq(MAGNESIUM_LO2, chan_idx); - }) - .set_coercer([this,chan_idx](double freq){ + }); + subtree->create<double>(rx_fe_path / "los" / MAGNESIUM_LO2 / "freq/value") + .set_publisher( + [this, chan_idx]() { return this->get_rx_lo_freq(MAGNESIUM_LO2, chan_idx); }) + .set_coercer([this, chan_idx](double freq) { return this->set_rx_lo_freq(freq, MAGNESIUM_LO2, chan_idx); }); - //TX LO - subtree->create<meta_range_t>(tx_fe_path / "los"/MAGNESIUM_LO1/"freq/range") - .set_publisher([this,chan_idx](){ + // TX LO + subtree->create<meta_range_t>(tx_fe_path / "los" / MAGNESIUM_LO1 / "freq/range") + .set_publisher([this, chan_idx]() { return this->get_rx_lo_freq_range(MAGNESIUM_LO1, chan_idx); - }) - ; - subtree->create<std::vector<std::string>>(tx_fe_path / "los"/MAGNESIUM_LO1/"source/options") - .set_publisher([this,chan_idx](){ + }); + subtree + ->create<std::vector<std::string>>( + tx_fe_path / "los" / MAGNESIUM_LO1 / "source/options") + .set_publisher([this, chan_idx]() { return this->get_tx_lo_sources(MAGNESIUM_LO1, chan_idx); - }) - ; - subtree->create<std::string>(tx_fe_path / "los"/MAGNESIUM_LO1/"source/value") - .add_coerced_subscriber([this,chan_idx](std::string src){ + }); + subtree->create<std::string>(tx_fe_path / "los" / MAGNESIUM_LO1 / "source/value") + .add_coerced_subscriber([this, chan_idx](std::string src) { this->set_tx_lo_source(src, MAGNESIUM_LO1, chan_idx); }) - .set_publisher([this,chan_idx](){ + .set_publisher([this, chan_idx]() { return this->get_tx_lo_source(MAGNESIUM_LO1, chan_idx); - }) - ; - subtree->create<double>(tx_fe_path / "los"/MAGNESIUM_LO1/"freq/value ") - .set_publisher([this,chan_idx](){ - return this->get_tx_lo_freq(MAGNESIUM_LO1, chan_idx); - }) - .set_coercer([this,chan_idx](double freq){ + }); + subtree->create<double>(tx_fe_path / "los" / MAGNESIUM_LO1 / "freq/value ") + .set_publisher( + [this, chan_idx]() { return this->get_tx_lo_freq(MAGNESIUM_LO1, chan_idx); }) + .set_coercer([this, chan_idx](double freq) { return this->set_tx_lo_freq(freq, MAGNESIUM_LO1, chan_idx); - }) - ; + }); - subtree->create<meta_range_t>(tx_fe_path / "los"/MAGNESIUM_LO2/"freq/range") - .set_publisher([this,chan_idx](){ - return this->get_tx_lo_freq_range(MAGNESIUM_LO2,chan_idx); - }) - ; - subtree->create<std::vector<std::string>>(tx_fe_path / "los"/MAGNESIUM_LO2/"source/options") - .set_publisher([this,chan_idx](){ + subtree->create<meta_range_t>(tx_fe_path / "los" / MAGNESIUM_LO2 / "freq/range") + .set_publisher([this, chan_idx]() { + return this->get_tx_lo_freq_range(MAGNESIUM_LO2, chan_idx); + }); + subtree + ->create<std::vector<std::string>>( + tx_fe_path / "los" / MAGNESIUM_LO2 / "source/options") + .set_publisher([this, chan_idx]() { return this->get_tx_lo_sources(MAGNESIUM_LO2, chan_idx); - }) - ; + }); - subtree->create<std::string>(tx_fe_path / "los"/MAGNESIUM_LO2/"source/value") - .add_coerced_subscriber([this,chan_idx](std::string src){ + subtree->create<std::string>(tx_fe_path / "los" / MAGNESIUM_LO2 / "source/value") + .add_coerced_subscriber([this, chan_idx](std::string src) { this->set_tx_lo_source(src, MAGNESIUM_LO2, chan_idx); }) - .set_publisher([this,chan_idx](){ + .set_publisher([this, chan_idx]() { return this->get_tx_lo_source(MAGNESIUM_LO2, chan_idx); - }) - ; - subtree->create<double>(tx_fe_path / "los"/MAGNESIUM_LO2/"freq/value") - .set_publisher([this,chan_idx](){ - return this->get_tx_lo_freq(MAGNESIUM_LO2, chan_idx); - }) - .set_coercer([this,chan_idx](double freq){ + }); + subtree->create<double>(tx_fe_path / "los" / MAGNESIUM_LO2 / "freq/value") + .set_publisher( + [this, chan_idx]() { return this->get_tx_lo_freq(MAGNESIUM_LO2, chan_idx); }) + .set_coercer([this, chan_idx](double freq) { return this->set_tx_lo_freq(freq, MAGNESIUM_LO2, chan_idx); }); } @@ -721,13 +560,11 @@ void magnesium_radio_ctrl_impl::_init_prop_tree() { const fs_path fe_base = fs_path("dboards") / _radio_slot; for (size_t chan_idx = 0; chan_idx < MAGNESIUM_NUM_CHANS; chan_idx++) { - this->_init_frontend_subtree( - _tree->subtree(fe_base), chan_idx); + this->_init_frontend_subtree(_tree->subtree(fe_base), chan_idx); } // EEPROM paths subject to change FIXME - _tree->create<eeprom_map_t>(_root_path / "eeprom") - .set(eeprom_map_t()); + _tree->create<eeprom_map_t>(_root_path / "eeprom").set(eeprom_map_t()); // TODO change codec names _tree->create<int>("rx_codecs" / _radio_slot / "gains"); @@ -736,94 +573,108 @@ void magnesium_radio_ctrl_impl::_init_prop_tree() _tree->create<std::string>("tx_codecs" / _radio_slot / "name").set("AD9371 Dual DAC"); // TODO remove this dirty hack - if (not _tree->exists("tick_rate")) - { - _tree->create<double>("tick_rate") - .set_publisher([this](){ return this->get_rate(); }) - ; + if (not _tree->exists("tick_rate")) { + _tree->create<double>("tick_rate").set_publisher([this]() { + return this->get_rate(); + }); } // *****FP_GPIO************************ - for(const auto& attr: usrp::gpio_atr::gpio_attr_map) { - if (not _tree->exists(fs_path("gpio") / "FP0" / attr.second)){ - switch (attr.first){ + for (const auto& attr : usrp::gpio_atr::gpio_attr_map) { + if (not _tree->exists(fs_path("gpio") / "FP0" / attr.second)) { + switch (attr.first) { case usrp::gpio_atr::GPIO_SRC: - //FIXME: move this creation of this branch of ptree out side of radio impl; - // since there's no data dependency between radio and SRC setting for FP0 - _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>( - 32, - usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr]( - const std::vector<std::string> str_val){ - uint32_t radio_src_value = 0; - uint32_t master_value = 0; - for(size_t i = 0 ; i<str_val.size(); i++){ - if(str_val[i] == "PS"){ - master_value += 1<<i;; - }else{ - auto port_num = extract_port_number(str_val[i],_tree); - radio_src_value =(1<<(2*i))*port_num + radio_src_value; + // FIXME: move this creation of this branch of ptree out side of + // radio impl; + // since there's no data dependency between radio and SRC setting for + // FP0 + _tree + ->create<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t radio_src_value = 0; + uint32_t master_value = 0; + for (size_t i = 0; i < str_val.size(); i++) { + if (str_val[i] == "PS") { + master_value += 1 << i; + ; + } else { + auto port_num = + extract_port_number(str_val[i], _tree); + radio_src_value = + (1 << (2 * i)) * port_num + radio_src_value; + } } - } - _rpcc->notify_with_token("set_fp_gpio_master", master_value); - _rpcc->notify_with_token("set_fp_gpio_radio_src", radio_src_value); - }); - break; + _rpcc->notify_with_token( + "set_fp_gpio_master", master_value); + _rpcc->notify_with_token( + "set_fp_gpio_radio_src", radio_src_value); + }); + break; case usrp::gpio_atr::GPIO_CTRL: case usrp::gpio_atr::GPIO_DDR: - _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>( - 32, - usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr]( - const std::vector<std::string> str_val){ - uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++){ - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i; - } - _fp_gpio->set_gpio_attr(attr.first, val); - }); + _tree + ->create<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t val = 0; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair + .at(attr.second) + .at(str_val[i]) + << i; + } + _fp_gpio->set_gpio_attr(attr.first, val); + }); break; - case usrp::gpio_atr::GPIO_READBACK:{ + case usrp::gpio_atr::GPIO_READBACK: { _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set_publisher([this](){ - return _fp_gpio->read_gpio(); - } - ); - } - break; + .set_publisher([this]() { return _fp_gpio->read_gpio(); }); + } break; default: _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set(0) - .add_coerced_subscriber([this, attr](const uint32_t val){ - _fp_gpio->set_gpio_attr(attr.first, val); - }); + .set(0) + .add_coerced_subscriber([this, attr](const uint32_t val) { + _fp_gpio->set_gpio_attr(attr.first, val); + }); } - }else{ - switch (attr.first){ + } else { + switch (attr.first) { case usrp::gpio_atr::GPIO_SRC: - break; + break; case usrp::gpio_atr::GPIO_CTRL: case usrp::gpio_atr::GPIO_DDR: - _tree->access<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr](const std::vector<std::string> str_val){ - uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++){ - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i; - } - _fp_gpio->set_gpio_attr(attr.first, val); - }); + _tree + ->access<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t val = 0; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair + .at(attr.second) + .at(str_val[i]) + << i; + } + _fp_gpio->set_gpio_attr(attr.first, val); + }); break; case usrp::gpio_atr::GPIO_READBACK: break; default: _tree->access<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set(0) - .add_coerced_subscriber([this, attr](const uint32_t val){ - _fp_gpio->set_gpio_attr(attr.first, val); - }); + .set(0) + .add_coerced_subscriber([this, attr](const uint32_t val) { + _fp_gpio->set_gpio_attr(attr.first, val); + }); } } } @@ -831,34 +682,27 @@ void magnesium_radio_ctrl_impl::_init_prop_tree() void magnesium_radio_ctrl_impl::_init_mpm_sensors( - const direction_t dir, - const size_t chan_idx -) { + const direction_t dir, const size_t chan_idx) +{ const std::string trx = (dir == RX_DIRECTION) ? "RX" : "TX"; - const fs_path fe_path = - fs_path("dboards") / _radio_slot / - (dir == RX_DIRECTION ? "rx_frontends" : "tx_frontends") / chan_idx; - auto sensor_list = - _rpcc->request_with_token<std::vector<std::string>>( - this->_rpc_prefix + "get_sensors", trx); + const fs_path fe_path = fs_path("dboards") / _radio_slot + / (dir == RX_DIRECTION ? "rx_frontends" : "tx_frontends") + / chan_idx; + auto sensor_list = _rpcc->request_with_token<std::vector<std::string>>( + this->_rpc_prefix + "get_sensors", trx); UHD_LOG_TRACE(unique_id(), - "Chan " << chan_idx << ": Found " - << sensor_list.size() << " " << trx << " sensors."); - for (const auto &sensor_name : sensor_list) { - UHD_LOG_TRACE(unique_id(), - "Adding " << trx << " sensor " << sensor_name); + "Chan " << chan_idx << ": Found " << sensor_list.size() << " " << trx + << " sensors."); + for (const auto& sensor_name : sensor_list) { + UHD_LOG_TRACE(unique_id(), "Adding " << trx << " sensor " << sensor_name); _tree->create<sensor_value_t>(fe_path / "sensors" / sensor_name) - .add_coerced_subscriber([](const sensor_value_t &){ - throw uhd::runtime_error( - "Attempting to write to sensor!"); + .add_coerced_subscriber([](const sensor_value_t&) { + throw uhd::runtime_error("Attempting to write to sensor!"); }) - .set_publisher([this, trx, sensor_name, chan_idx](){ + .set_publisher([this, trx, sensor_name, chan_idx]() { return sensor_value_t( this->_rpcc->request_with_token<sensor_value_t::sensor_map_t>( - this->_rpc_prefix + "get_sensor", - trx, sensor_name, chan_idx) - ); - }) - ; + this->_rpc_prefix + "get_sensor", trx, sensor_name, chan_idx)); + }); } } diff --git a/host/lib/usrp/dboard/neon/neon_ad9361_iface.cpp b/host/lib/usrp/dboard/neon/neon_ad9361_iface.cpp index e19f890ca..a9cf28fc2 100644 --- a/host/lib/usrp/dboard/neon/neon_ad9361_iface.cpp +++ b/host/lib/usrp/dboard/neon/neon_ad9361_iface.cpp @@ -14,38 +14,33 @@ using namespace uhd; class neon_ad9361_iface : public ad9361_ctrl { public: - neon_ad9361_iface( - rpc_client::sptr rpcc - ) : _rpcc(rpcc) - , _rpc_prefix("db_0_") - , _log_prefix("AD9361") + neon_ad9361_iface(rpc_client::sptr rpcc) + : _rpcc(rpcc), _rpc_prefix("db_0_"), _log_prefix("AD9361") { - UHD_LOG_TRACE(_log_prefix, - "Initialized controls with RPC prefix " << _rpc_prefix); + UHD_LOG_TRACE( + _log_prefix, "Initialized controls with RPC prefix " << _rpc_prefix); } - double set_bw_filter(const std::string &which, const double bw) + double set_bw_filter(const std::string& which, const double bw) { return _rpcc->request_with_token<double>( this->_rpc_prefix + "set_bw_filter", which, bw); } - double set_gain(const std::string &which, const double value) + double set_gain(const std::string& which, const double value) { return _rpcc->request_with_token<double>( this->_rpc_prefix + "set_gain", which, value); } - void set_agc(const std::string &which, bool enable) + void set_agc(const std::string& which, bool enable) { - _rpcc->request_with_token<void>( - this->_rpc_prefix + "set_agc", which, enable); + _rpcc->request_with_token<void>(this->_rpc_prefix + "set_agc", which, enable); } - void set_agc_mode(const std::string &which, const std::string &mode) + void set_agc_mode(const std::string& which, const std::string& mode) { - _rpcc->request_with_token<void>( - this->_rpc_prefix + "set_agc_mode", which, mode); + _rpcc->request_with_token<void>(this->_rpc_prefix + "set_agc_mode", which, mode); } double set_clock_rate(const double rate) @@ -60,43 +55,41 @@ public: this->_rpc_prefix + "set_active_chains", tx1, tx2, rx1, rx2); } - double tune(const std::string &which, const double value) + double tune(const std::string& which, const double value) { return _rpcc->request_with_token<double>( this->_rpc_prefix + "tune", which, value); } - void set_dc_offset_auto(const std::string &which, const bool on) + void set_dc_offset_auto(const std::string& which, const bool on) { _rpcc->request_with_token<void>( this->_rpc_prefix + "set_dc_offset_auto", which, on); } - void set_timing_mode(const std::string &timing_mode) + void set_timing_mode(const std::string& timing_mode) { _rpcc->request_with_token<void>( this->_rpc_prefix + "set_timing_mode", timing_mode); } - void set_iq_balance_auto(const std::string &which, const bool on) + void set_iq_balance_auto(const std::string& which, const bool on) { _rpcc->request_with_token<void>( this->_rpc_prefix + "set_iq_balance_auto", which, on); } - double get_freq(const std::string &which) + double get_freq(const std::string& which) { - return _rpcc->request_with_token<double>( - this->_rpc_prefix + "get_freq", which); + return _rpcc->request_with_token<double>(this->_rpc_prefix + "get_freq", which); } void data_port_loopback(const bool on) { - _rpcc->request_with_token<void>( - this->_rpc_prefix + "data_port_loopback", on); + _rpcc->request_with_token<void>(this->_rpc_prefix + "data_port_loopback", on); } - sensor_value_t get_rssi(const std::string &which) + sensor_value_t get_rssi(const std::string& which) { return sensor_value_t(_rpcc->request_with_token<sensor_value_t::sensor_map_t>( this->_rpc_prefix + "get_rssi", which)); @@ -108,23 +101,25 @@ public: this->_rpc_prefix + "get_temperature")); } - std::vector<std::string> get_filter_names(const std::string &which) + std::vector<std::string> get_filter_names(const std::string& which) { return _rpcc->request_with_token<std::vector<std::string>>( this->_rpc_prefix + "get_filter_names", which); } - filter_info_base::sptr get_filter(const std::string &/*which*/, - const std::string &/*filter_name*/) + filter_info_base::sptr get_filter( + const std::string& /*which*/, const std::string& /*filter_name*/) { - throw uhd::runtime_error("ad9361_ctrl::get_filter is not supported over an RPC connection"); + throw uhd::runtime_error( + "ad9361_ctrl::get_filter is not supported over an RPC connection"); } - void set_filter(const std::string &/*which*/, - const std::string &/*filter_name*/, - const filter_info_base::sptr /*filter*/) + void set_filter(const std::string& /*which*/, + const std::string& /*filter_name*/, + const filter_info_base::sptr /*filter*/) { - throw uhd::runtime_error("ad9361_ctrl::set_filter is not supported over an RPC connection"); + throw uhd::runtime_error( + "ad9361_ctrl::set_filter is not supported over an RPC connection"); } void output_digital_test_tone(bool enb) @@ -150,13 +145,11 @@ ad9361_ctrl::sptr make_rpc(rpc_client::sptr rpcc) return ad9361_ctrl::sptr(new neon_ad9361_iface(rpcc)); } -/*! Helper function to convert direction and channel to the 'which' required by most Catalina - driver functions */ +/*! Helper function to convert direction and channel to the 'which' required by most + Catalina driver functions */ std::string get_which_ad9361_chain(const direction_t dir, const size_t chan) { UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); UHD_ASSERT_THROW(chan == 0 or chan == 1); - return str(boost::format("%s%d") - % (dir == RX_DIRECTION ? "RX" : "TX") - % (chan + 1)); + return str(boost::format("%s%d") % (dir == RX_DIRECTION ? "RX" : "TX") % (chan + 1)); } diff --git a/host/lib/usrp/dboard/neon/neon_bands.cpp b/host/lib/usrp/dboard/neon/neon_bands.cpp index 25aa0a181..303d2801d 100644 --- a/host/lib/usrp/dboard/neon/neon_bands.cpp +++ b/host/lib/usrp/dboard/neon/neon_bands.cpp @@ -4,8 +4,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "neon_radio_ctrl_impl.hpp" #include "neon_constants.hpp" +#include "neon_radio_ctrl_impl.hpp" #include <uhd/utils/math.hpp> /* @@ -51,54 +51,55 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - /* Note on the RX filter bank: - * - * The RX path has 7 bands, which we call LB_B2, B3, .. HB same as - * the schematic. - * - * The following constants define lower cutoff frequencies for each band. - * LB_B2 does not have a lower cutoff frequency, it is implied by - * AD9361_MIN_FREQ. NEON_RX_BAND1_MIN_FREQ is the cutover frequency - * for switching from LB_B2 to LB_B3, and so on. - * - * Bands 1-6 have both high- and low-pass filters (effectively band - * passes). Frequencies need to be chosen to allow as much of the full - * bandwidth through unattenuated. - */ - constexpr double NEON_RX_LB_BAND3_MIN_FREQ = 450e6; - constexpr double NEON_RX_LB_BAND4_MIN_FREQ = 700e6; - constexpr double NEON_RX_LB_BAND5_MIN_FREQ = 1200e6; - constexpr double NEON_RX_LB_BAND6_MIN_FREQ = 1800e6; - constexpr double NEON_RX_LB_BAND7_MIN_FREQ = 2350e6; - constexpr double NEON_RX_HB_MIN_FREQ = 2600e6; +/* Note on the RX filter bank: + * + * The RX path has 7 bands, which we call LB_B2, B3, .. HB same as + * the schematic. + * + * The following constants define lower cutoff frequencies for each band. + * LB_B2 does not have a lower cutoff frequency, it is implied by + * AD9361_MIN_FREQ. NEON_RX_BAND1_MIN_FREQ is the cutover frequency + * for switching from LB_B2 to LB_B3, and so on. + * + * Bands 1-6 have both high- and low-pass filters (effectively band + * passes). Frequencies need to be chosen to allow as much of the full + * bandwidth through unattenuated. + */ +constexpr double NEON_RX_LB_BAND3_MIN_FREQ = 450e6; +constexpr double NEON_RX_LB_BAND4_MIN_FREQ = 700e6; +constexpr double NEON_RX_LB_BAND5_MIN_FREQ = 1200e6; +constexpr double NEON_RX_LB_BAND6_MIN_FREQ = 1800e6; +constexpr double NEON_RX_LB_BAND7_MIN_FREQ = 2350e6; +constexpr double NEON_RX_HB_MIN_FREQ = 2600e6; - /* Note on the TX filter bank: - * - * The TX path has 9 bands, which we name according to the schematic. - * - * The following constants define lower cutoff frequencies for each band. - * LB_80 does not have a lower cutoff frequency, it is implied by - * AD9361_MIN_FREQ. NEON_TX_LB_160_MIN_FREQ is the cutover frequency - * for switching from LB_80 to LB_160, and so on. - * - * On current Neon revisions, all filters on the TX filter bank are - * low pass filters (no high pass filters). - * Frequencies need to be chosen to allow as much of the full bandwidth - * through unattenuated (so don't go all the way up to the cutoff frequency - * of that filter). - */ - constexpr double NEON_TX_LB_160_MIN_FREQ = 117.7e6; - constexpr double NEON_TX_LB_225_MIN_FREQ = 178.2e6; - constexpr double NEON_TX_LB_400_MIN_FREQ = 284.3e6; - constexpr double NEON_TX_LB_575_MIN_FREQ = 453.7e6; - constexpr double NEON_TX_LB_1000_MIN_FREQ = 723.8e6; - constexpr double NEON_TX_LB_1700_MIN_FREQ = 1154.9e6; - constexpr double NEON_TX_LB_2750_MIN_FREQ = 1842.6e6; - constexpr double NEON_TX_HB_MIN_FREQ = 2940.0e6; -} +/* Note on the TX filter bank: + * + * The TX path has 9 bands, which we name according to the schematic. + * + * The following constants define lower cutoff frequencies for each band. + * LB_80 does not have a lower cutoff frequency, it is implied by + * AD9361_MIN_FREQ. NEON_TX_LB_160_MIN_FREQ is the cutover frequency + * for switching from LB_80 to LB_160, and so on. + * + * On current Neon revisions, all filters on the TX filter bank are + * low pass filters (no high pass filters). + * Frequencies need to be chosen to allow as much of the full bandwidth + * through unattenuated (so don't go all the way up to the cutoff frequency + * of that filter). + */ +constexpr double NEON_TX_LB_160_MIN_FREQ = 117.7e6; +constexpr double NEON_TX_LB_225_MIN_FREQ = 178.2e6; +constexpr double NEON_TX_LB_400_MIN_FREQ = 284.3e6; +constexpr double NEON_TX_LB_575_MIN_FREQ = 453.7e6; +constexpr double NEON_TX_LB_1000_MIN_FREQ = 723.8e6; +constexpr double NEON_TX_LB_1700_MIN_FREQ = 1154.9e6; +constexpr double NEON_TX_LB_2750_MIN_FREQ = 1842.6e6; +constexpr double NEON_TX_HB_MIN_FREQ = 2940.0e6; +} // namespace -neon_radio_ctrl_impl::rx_band -neon_radio_ctrl_impl::_map_freq_to_rx_band(const double freq) { +neon_radio_ctrl_impl::rx_band neon_radio_ctrl_impl::_map_freq_to_rx_band( + const double freq) +{ neon_radio_ctrl_impl::rx_band band; if (fp_compare_epsilon<double>(freq) < AD9361_RX_MIN_FREQ) { @@ -124,8 +125,9 @@ neon_radio_ctrl_impl::_map_freq_to_rx_band(const double freq) { return band; } -neon_radio_ctrl_impl::tx_band -neon_radio_ctrl_impl::_map_freq_to_tx_band(const double freq) { +neon_radio_ctrl_impl::tx_band neon_radio_ctrl_impl::_map_freq_to_tx_band( + const double freq) +{ neon_radio_ctrl_impl::tx_band band; if (fp_compare_epsilon<double>(freq) < AD9361_TX_MIN_FREQ) { @@ -154,4 +156,3 @@ neon_radio_ctrl_impl::_map_freq_to_tx_band(const double freq) { return band; } - diff --git a/host/lib/usrp/dboard/neon/neon_constants.hpp b/host/lib/usrp/dboard/neon/neon_constants.hpp index 58e5244fc..42cfb6579 100644 --- a/host/lib/usrp/dboard/neon/neon_constants.hpp +++ b/host/lib/usrp/dboard/neon/neon_constants.hpp @@ -7,16 +7,16 @@ #ifndef INCLUDED_LIBUHD_NEON_CONSTANTS_HPP #define INCLUDED_LIBUHD_NEON_CONSTANTS_HPP -#include <vector> -#include <string> #include <cstddef> +#include <string> +#include <vector> -static constexpr size_t FPGPIO_MASTER_RADIO = 0; -static constexpr size_t TOTAL_RADIO_PORTS = 2; -static constexpr double AD9361_RX_MIN_BANDWIDTH = 20.0e6; // HZ +static constexpr size_t FPGPIO_MASTER_RADIO = 0; +static constexpr size_t TOTAL_RADIO_PORTS = 2; +static constexpr double AD9361_RX_MIN_BANDWIDTH = 20.0e6; // HZ static constexpr double AD9361_RX_MAX_BANDWIDTH = 40.0e6; // HZ -static constexpr double AD9361_TX_MIN_BANDWIDTH = 20.0e6; // HZ +static constexpr double AD9361_TX_MIN_BANDWIDTH = 20.0e6; // HZ static constexpr double AD9361_TX_MAX_BANDWIDTH = 40.0e6; // HZ static constexpr double AD9361_TX_MIN_FREQ = 47.0e6; // Hz @@ -27,27 +27,25 @@ static constexpr double AD9361_RX_MAX_FREQ = 6.0e9; // Hz static constexpr double NEON_RADIO_RATE = 16e6; // Hz -static constexpr double AD9361_MIN_RX_GAIN = 0.0; // dB -static constexpr double AD9361_MAX_RX_GAIN = 76; // dB +static constexpr double AD9361_MIN_RX_GAIN = 0.0; // dB +static constexpr double AD9361_MAX_RX_GAIN = 76; // dB static constexpr double AD9361_RX_GAIN_STEP = 1.0; // dB -static constexpr double AD9361_MIN_TX_GAIN = 0.0; // dB -static constexpr double AD9361_MAX_TX_GAIN = 89.75; // dB +static constexpr double AD9361_MIN_TX_GAIN = 0.0; // dB +static constexpr double AD9361_MAX_TX_GAIN = 89.75; // dB static constexpr double AD9361_TX_GAIN_STEP = 0.25; // dB -static constexpr bool NEON_DEFAULT_AUTO_DC_OFFSET = true; +static constexpr bool NEON_DEFAULT_AUTO_DC_OFFSET = true; static constexpr bool NEON_DEFAULT_AUTO_IQ_BALANCE = true; -static constexpr bool NEON_DEFAULT_AGC_ENABLE = false; +static constexpr bool NEON_DEFAULT_AGC_ENABLE = false; -static constexpr double NEON_DEFAULT_GAIN = 0.0; -static constexpr double NEON_DEFAULT_FREQ = 2.4e9; // Hz -static constexpr double NEON_DEFAULT_BANDWIDTH = 40e6; // Hz -static constexpr char NEON_DEFAULT_RX_ANTENNA[] = "RX2"; -static constexpr char NEON_DEFAULT_TX_ANTENNA[] = "TX/RX"; +static constexpr double NEON_DEFAULT_GAIN = 0.0; +static constexpr double NEON_DEFAULT_FREQ = 2.4e9; // Hz +static constexpr double NEON_DEFAULT_BANDWIDTH = 40e6; // Hz +static constexpr char NEON_DEFAULT_RX_ANTENNA[] = "RX2"; +static constexpr char NEON_DEFAULT_TX_ANTENNA[] = "TX/RX"; -static const std::vector<std::string> NEON_RX_ANTENNAS = { - "RX2", "TX/RX" -}; +static const std::vector<std::string> NEON_RX_ANTENNAS = {"RX2", "TX/RX"}; static constexpr size_t NEON_NUM_CHANS = 2; diff --git a/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.cpp index 71e467848..d8fabcee0 100644 --- a/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.cpp @@ -7,20 +7,20 @@ #include "neon_radio_ctrl_impl.hpp" #include "neon_constants.hpp" #include "neon_regs.hpp" -#include <uhd/utils/log.hpp> +#include <uhd/exception.hpp> #include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/transport/chdr.hpp> -#include <uhd/utils/algorithm.hpp> -#include <uhd/utils/math.hpp> #include <uhd/types/direction.hpp> #include <uhd/types/eeprom.hpp> -#include <uhd/exception.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <boost/algorithm/string.hpp> -#include <boost/make_shared.hpp> #include <boost/format.hpp> -#include <sstream> +#include <boost/make_shared.hpp> #include <cmath> #include <cstdlib> +#include <sstream> using namespace uhd; using namespace uhd::usrp; @@ -34,7 +34,7 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(neon_radio_ctrl) { UHD_LOG_TRACE(unique_id(), "Entering neon_radio_ctrl_impl ctor..."); const char radio_slot_name[1] = {'A'}; - _radio_slot = radio_slot_name[get_block_id().get_block_count()]; + _radio_slot = radio_slot_name[get_block_id().get_block_count()]; UHD_LOG_TRACE(unique_id(), "Radio slot: " << _radio_slot); _rpc_prefix = "db_0_"; @@ -58,38 +58,39 @@ bool neon_radio_ctrl_impl::check_radio_config() // mapping of frontend to radio perif index static const size_t FE0 = 0; static const size_t FE1 = 1; - const size_t num_rx = _is_streamer_active(RX_DIRECTION, FE0) + _is_streamer_active(RX_DIRECTION, FE1); - const size_t num_tx = _is_streamer_active(TX_DIRECTION, FE0) + _is_streamer_active(TX_DIRECTION, FE1); + const size_t num_rx = + _is_streamer_active(RX_DIRECTION, FE0) + _is_streamer_active(RX_DIRECTION, FE1); + const size_t num_tx = + _is_streamer_active(TX_DIRECTION, FE0) + _is_streamer_active(TX_DIRECTION, FE1); - //setup the active chains in the codec + // setup the active chains in the codec if ((num_rx + num_tx) == 0) { // Ensure at least one RX chain is enabled so AD9361 outputs a sample clock this->set_streaming_mode(false, false, true, false); } else { - this->set_streaming_mode( - _is_streamer_active(TX_DIRECTION, FE0), - _is_streamer_active(TX_DIRECTION, FE1), - _is_streamer_active(RX_DIRECTION, FE0), - _is_streamer_active(RX_DIRECTION, FE1) - ); + this->set_streaming_mode(_is_streamer_active(TX_DIRECTION, FE0), + _is_streamer_active(TX_DIRECTION, FE1), + _is_streamer_active(RX_DIRECTION, FE0), + _is_streamer_active(RX_DIRECTION, FE1)); } return true; } -void neon_radio_ctrl_impl::set_streaming_mode(const bool tx1, const bool tx2, const bool rx1, const bool rx2) +void neon_radio_ctrl_impl::set_streaming_mode( + const bool tx1, const bool tx2, const bool rx1, const bool rx2) { UHD_LOG_TRACE(unique_id(), "Setting up streaming ...") const size_t num_rx = rx1 + rx2; const size_t num_tx = tx1 + tx2; - //setup the active chains in the codec + // setup the active chains in the codec _ad9361->set_active_chains(tx1, tx2, rx1, rx2); const std::string TIMING_MODE_2R2T = "2R2T"; const std::string TIMING_MODE_1R1T = "1R1T"; - const std::string MIMO = "MIMO"; // 2R2T - const std::string SISO_TX1 = "SISO_TX1"; // 1R1T - const std::string SISO_TX0 = "SISO_TX0"; // 1R1T + const std::string MIMO = "MIMO"; // 2R2T + const std::string SISO_TX1 = "SISO_TX1"; // 1R1T + const std::string SISO_TX0 = "SISO_TX0"; // 1R1T // setup 1R1T/2R2T mode in catalina and fpga // The Catalina interface in the fpga needs to know which TX channel to use for // the data on the LVDS lines. @@ -107,11 +108,11 @@ void neon_radio_ctrl_impl::set_streaming_mode(const bool tx1, const bool tx2, co } } -void neon_radio_ctrl_impl::set_channel_mode(const std::string &channel_mode) +void neon_radio_ctrl_impl::set_channel_mode(const std::string& channel_mode) { - //MIMO for 2R2T mode for 2 channels - //SISO_TX1 for 1R1T mode for 1 channel - TX1 - //SISO_TX0 for 1R1T mode for 1 channel - TX0 + // MIMO for 2R2T mode for 2 channels + // SISO_TX1 for 1R1T mode for 1 channel - TX1 + // SISO_TX0 for 1R1T mode for 1 channel - TX0 _rpcc->request_with_token<void>("set_channel_mode", channel_mode); } @@ -127,9 +128,8 @@ void neon_radio_ctrl_impl::set_channel_mode(const std::string &channel_mode) Note: This currently only tests 2R2T mode */ void neon_radio_ctrl_impl::loopback_self_test( - std::function<void(uint32_t)> poker_functor, - std::function<uint64_t()> peeker_functor -) { + std::function<void(uint32_t)> poker_functor, std::function<uint64_t()> peeker_functor) +{ // Save current rate before running this test const double current_rate = this->get_rate(); // Set 2R2T mode, stream on all channels @@ -139,7 +139,7 @@ void neon_radio_ctrl_impl::loopback_self_test( // Put AD936x in loopback mode _ad9361->data_port_loopback(true); UHD_LOG_INFO(unique_id(), "Performing CODEC loopback test... "); - size_t hash = size_t(time(NULL)); + size_t hash = size_t(time(NULL)); constexpr size_t loopback_count = 100; // Allow some time for AD936x to enter loopback mode. @@ -150,27 +150,26 @@ void neon_radio_ctrl_impl::loopback_self_test( // Sleeping 1ms is far more than enough. std::this_thread::sleep_for(std::chrono::milliseconds(1)); - for (size_t i = 0; i < loopback_count; i++) - { + for (size_t i = 0; i < loopback_count; i++) { // Create test word boost::hash_combine(hash, i); const uint32_t word32 = uint32_t(hash) & 0xfff0fff0; - //const uint32_t word32 = 0xCA00C100; + // const uint32_t word32 = 0xCA00C100; // Write test word to codec_idle idle register (on TX side) poker_functor(word32); // Read back values - TX is lower 32-bits and RX is upper 32-bits const uint64_t rb_word64 = peeker_functor(); - const uint32_t rb_tx = uint32_t(rb_word64 >> 32); - const uint32_t rb_rx = uint32_t(rb_word64 & 0xffffffff); + const uint32_t rb_tx = uint32_t(rb_word64 >> 32); + const uint32_t rb_rx = uint32_t(rb_word64 & 0xffffffff); // Compare TX and RX values to test word bool test_fail = word32 != rb_tx or word32 != rb_rx; - if(test_fail) - { - UHD_LOG_WARNING(unique_id(), "CODEC loopback test failed! " - << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") - % word32 % rb_tx % rb_rx); + if (test_fail) { + UHD_LOG_WARNING(unique_id(), + "CODEC loopback test failed! " + << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") + % word32 % rb_tx % rb_rx); throw uhd::runtime_error("CODEC loopback test failed."); } } @@ -189,63 +188,50 @@ void neon_radio_ctrl_impl::loopback_self_test( double neon_radio_ctrl_impl::set_rate(const double rate) { std::lock_guard<std::mutex> l(_set_lock); - UHD_LOG_DEBUG(unique_id(), "Asking for clock rate " << rate/1e6 << " MHz\n"); + UHD_LOG_DEBUG(unique_id(), "Asking for clock rate " << rate / 1e6 << " MHz\n"); double actual_tick_rate = _ad9361->set_clock_rate(rate); - UHD_LOG_DEBUG(unique_id(), "Actual clock rate " << actual_tick_rate/1e6 << " MHz\n"); + UHD_LOG_DEBUG( + unique_id(), "Actual clock rate " << actual_tick_rate / 1e6 << " MHz\n"); radio_ctrl_impl::set_rate(rate); return rate; } -void neon_radio_ctrl_impl::set_tx_antenna( - const std::string &ant, - const size_t chan -) { +void neon_radio_ctrl_impl::set_tx_antenna(const std::string& ant, const size_t chan) +{ if (ant != get_tx_antenna(chan)) { - throw uhd::value_error(str( - boost::format("[%s] Requesting invalid TX antenna value: %s") - % unique_id() - % ant - )); + throw uhd::value_error( + str(boost::format("[%s] Requesting invalid TX antenna value: %s") + % unique_id() % ant)); } radio_ctrl_impl::set_tx_antenna(ant, chan); // We can't actually set the TX antenna, so let's stop here. } -void neon_radio_ctrl_impl::set_rx_antenna( - const std::string &ant, - const size_t chan -) { +void neon_radio_ctrl_impl::set_rx_antenna(const std::string& ant, const size_t chan) +{ UHD_ASSERT_THROW(chan <= NEON_NUM_CHANS); - if (std::find(NEON_RX_ANTENNAS.begin(), - NEON_RX_ANTENNAS.end(), - ant) == NEON_RX_ANTENNAS.end()) { - throw uhd::value_error(str( - boost::format("[%s] Requesting invalid RX antenna value: %s") - % unique_id() - % ant - )); + if (std::find(NEON_RX_ANTENNAS.begin(), NEON_RX_ANTENNAS.end(), ant) + == NEON_RX_ANTENNAS.end()) { + throw uhd::value_error( + str(boost::format("[%s] Requesting invalid RX antenna value: %s") + % unique_id() % ant)); } - UHD_LOG_TRACE(unique_id(), - "Setting RX antenna to " << ant << " for chan " << chan); + UHD_LOG_TRACE(unique_id(), "Setting RX antenna to " << ant << " for chan " << chan); radio_ctrl_impl::set_rx_antenna(ant, chan); _set_atr_bits(chan); } -double neon_radio_ctrl_impl::set_tx_frequency( - const double freq, - const size_t chan -) { - UHD_LOG_TRACE(unique_id(), - "set_tx_frequency(f=" << freq << ", chan=" << chan << ")"); +double neon_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan) +{ + UHD_LOG_TRACE(unique_id(), "set_tx_frequency(f=" << freq << ", chan=" << chan << ")"); std::lock_guard<std::mutex> l(_set_lock); double clipped_freq = uhd::clip(freq, AD9361_TX_MIN_FREQ, AD9361_TX_MAX_FREQ); - double coerced_freq = _ad9361->tune( - get_which_ad9361_chain(TX_DIRECTION, chan), - clipped_freq); + double coerced_freq = + _ad9361->tune(get_which_ad9361_chain(TX_DIRECTION, chan), clipped_freq); radio_ctrl_impl::set_tx_frequency(coerced_freq, chan); // Front-end switching _set_atr_bits(chan); @@ -253,19 +239,15 @@ double neon_radio_ctrl_impl::set_tx_frequency( return coerced_freq; } -double neon_radio_ctrl_impl::set_rx_frequency( - const double freq, - const size_t chan -) { - UHD_LOG_TRACE(unique_id(), - "set_rx_frequency(f=" << freq << ", chan=" << chan << ")"); +double neon_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan) +{ + UHD_LOG_TRACE(unique_id(), "set_rx_frequency(f=" << freq << ", chan=" << chan << ")"); std::lock_guard<std::mutex> l(_set_lock); double clipped_freq = uhd::clip(freq, AD9361_RX_MIN_FREQ, AD9361_RX_MAX_FREQ); - double coerced_freq = _ad9361->tune( - get_which_ad9361_chain(RX_DIRECTION, chan), - clipped_freq); + double coerced_freq = + _ad9361->tune(get_which_ad9361_chain(RX_DIRECTION, chan), clipped_freq); radio_ctrl_impl::set_rx_frequency(coerced_freq, chan); // Front-end switching _set_atr_bits(chan); @@ -273,63 +255,48 @@ double neon_radio_ctrl_impl::set_rx_frequency( return coerced_freq; } -double neon_radio_ctrl_impl::set_rx_bandwidth( - const double bandwidth, - const size_t chan -) { +double neon_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); - double clipped_bw = _ad9361->set_bw_filter( - get_which_ad9361_chain(RX_DIRECTION, chan), - bandwidth); + double clipped_bw = + _ad9361->set_bw_filter(get_which_ad9361_chain(RX_DIRECTION, chan), bandwidth); return radio_ctrl_impl::set_rx_bandwidth(clipped_bw, chan); } -double neon_radio_ctrl_impl::set_tx_bandwidth( - const double bandwidth, - const size_t chan -) { +double neon_radio_ctrl_impl::set_tx_bandwidth(const double bandwidth, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); - double clipped_bw = _ad9361->set_bw_filter( - get_which_ad9361_chain(TX_DIRECTION, chan), - bandwidth); + double clipped_bw = + _ad9361->set_bw_filter(get_which_ad9361_chain(TX_DIRECTION, chan), bandwidth); return radio_ctrl_impl::set_tx_bandwidth(clipped_bw, chan); } -double neon_radio_ctrl_impl::set_tx_gain( - const double gain, - const size_t chan -) { +double neon_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); - UHD_LOG_TRACE(unique_id(), - "set_tx_gain(gain=" << gain << ", chan=" << chan << ")"); + UHD_LOG_TRACE(unique_id(), "set_tx_gain(gain=" << gain << ", chan=" << chan << ")"); double clip_gain = uhd::clip(gain, AD9361_MIN_TX_GAIN, AD9361_MAX_TX_GAIN); - _ad9361->set_gain( - get_which_ad9361_chain(TX_DIRECTION, chan), - clip_gain); + _ad9361->set_gain(get_which_ad9361_chain(TX_DIRECTION, chan), clip_gain); radio_ctrl_impl::set_tx_gain(clip_gain, chan); return clip_gain; } -double neon_radio_ctrl_impl::set_rx_gain( - const double gain, - const size_t chan -) { +double neon_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan) +{ std::lock_guard<std::mutex> l(_set_lock); - UHD_LOG_TRACE(unique_id(), - "set_rx_gain(gain=" << gain << ", chan=" << chan << ")"); + UHD_LOG_TRACE(unique_id(), "set_rx_gain(gain=" << gain << ", chan=" << chan << ")"); double clip_gain = uhd::clip(gain, AD9361_MIN_RX_GAIN, AD9361_MAX_RX_GAIN); - _ad9361->set_gain( - get_which_ad9361_chain(RX_DIRECTION, chan), - clip_gain); + _ad9361->set_gain(get_which_ad9361_chain(RX_DIRECTION, chan), clip_gain); radio_ctrl_impl::set_rx_gain(clip_gain, chan); return clip_gain; } size_t neon_radio_ctrl_impl::get_chan_from_dboard_fe( - const std::string &fe, const direction_t /* dir */ -) { + const std::string& fe, const direction_t /* dir */ +) +{ const size_t chan = boost::lexical_cast<size_t>(fe); - if (chan > _get_num_radios()-1) { + if (chan > _get_num_radios() - 1) { UHD_LOG_WARNING(unique_id(), boost::format("Invalid channel determined from dboard frontend %s.") % fe); } @@ -337,122 +304,107 @@ size_t neon_radio_ctrl_impl::get_chan_from_dboard_fe( } std::string neon_radio_ctrl_impl::get_dboard_fe_from_chan( - const size_t chan, - const direction_t /* dir */ -) { + const size_t chan, const direction_t /* dir */ +) +{ return std::to_string(chan); } void neon_radio_ctrl_impl::set_rpc_client( - uhd::rpc_client::sptr rpcc, - const uhd::device_addr_t &block_args -) { - _rpcc = rpcc; + uhd::rpc_client::sptr rpcc, const uhd::device_addr_t& block_args) +{ + _rpcc = rpcc; _block_args = block_args; UHD_LOG_TRACE(unique_id(), "Instantiating AD9361 control object..."); _ad9361 = make_rpc(_rpcc); UHD_LOG_TRACE(unique_id(), "Setting Catalina Defaults... "); - //Initialize catalina + // Initialize catalina this->_init_codec(); if (block_args.has_key("identify")) { const std::string identify_val = block_args.get("identify"); - int identify_duration = std::atoi(identify_val.c_str()); + int identify_duration = std::atoi(identify_val.c_str()); if (identify_duration == 0) { identify_duration = 5; } UHD_LOG_INFO(unique_id(), "Running LED identification process for " << identify_duration - << " seconds."); + << " seconds."); _identify_with_leds(identify_duration); } // Note: MCR gets set during the init() call (prior to this), which takes // in arguments from the device args. So if block_args contains a // master_clock_rate key, then it should better be whatever the device is // configured to do. - _master_clock_rate = _rpcc->request_with_token<double>( - _rpc_prefix + "get_master_clock_rate"); + _master_clock_rate = + _rpcc->request_with_token<double>(_rpc_prefix + "get_master_clock_rate"); if (block_args.cast<double>("master_clock_rate", _master_clock_rate) - != _master_clock_rate) { + != _master_clock_rate) { throw uhd::runtime_error(str( boost::format("Master clock rate mismatch. Device returns %f MHz, " "but should have been %f MHz.") % (_master_clock_rate / 1e6) - % (block_args.cast<double>( - "master_clock_rate", _master_clock_rate) / 1e6) - )); - + % (block_args.cast<double>("master_clock_rate", _master_clock_rate) / 1e6))); } - UHD_LOG_DEBUG(unique_id(), - "Master Clock Rate is: " << (_master_clock_rate / 1e6) << " MHz."); + UHD_LOG_DEBUG( + unique_id(), "Master Clock Rate is: " << (_master_clock_rate / 1e6) << " MHz."); this->set_rate(_master_clock_rate); // Loopback test for (size_t chan = 0; chan < _get_num_radios(); chan++) { loopback_self_test( - [this, chan](const uint32_t value){ - this->sr_write(regs::CODEC_IDLE, value, chan); - }, - [this, chan](){ + [this, chan]( + const uint32_t value) { this->sr_write(regs::CODEC_IDLE, value, chan); }, + [this, chan]() { return this->user_reg_read64(regs::RB_CODEC_READBACK, chan); - } - ); + }); } const size_t db_idx = get_block_id().get_block_count(); _tree->access<eeprom_map_t>(_root_path / "eeprom") - .add_coerced_subscriber([this, db_idx](const eeprom_map_t& db_eeprom){ + .add_coerced_subscriber([this, db_idx](const eeprom_map_t& db_eeprom) { this->_rpcc->notify_with_token("set_db_eeprom", db_idx, db_eeprom); }) - .set_publisher([this, db_idx](){ - return this->_rpcc->request_with_token<eeprom_map_t>( - "get_db_eeprom", db_idx - ); - }) - ; + .set_publisher([this, db_idx]() { + return this->_rpcc->request_with_token<eeprom_map_t>("get_db_eeprom", db_idx); + }); // Init sensors - for (const auto &dir : std::vector<direction_t>{RX_DIRECTION, TX_DIRECTION}) { + for (const auto& dir : std::vector<direction_t>{RX_DIRECTION, TX_DIRECTION}) { for (size_t chan_idx = 0; chan_idx < NEON_NUM_CHANS; chan_idx++) { _init_mpm_sensors(dir, chan_idx); } } } -bool neon_radio_ctrl_impl::get_lo_lock_status( - const direction_t dir -) { - if (not (bool(_rpcc))) { - UHD_LOG_DEBUG(unique_id(), - "Reported no LO lock due to lack of RPC connection."); +bool neon_radio_ctrl_impl::get_lo_lock_status(const direction_t dir) +{ + if (not(bool(_rpcc))) { + UHD_LOG_DEBUG(unique_id(), "Reported no LO lock due to lack of RPC connection."); return false; } const std::string trx = (dir == RX_DIRECTION) ? "rx" : "tx"; - bool lo_lock = _rpcc->request_with_token<bool>( - _rpc_prefix + "get_ad9361_lo_lock", trx); + bool lo_lock = + _rpcc->request_with_token<bool>(_rpc_prefix + "get_ad9361_lo_lock", trx); UHD_LOG_TRACE(unique_id(), "AD9361 " << trx << " LO reports lock: " << (lo_lock ? "Yes" : "No")); return lo_lock; } -void neon_radio_ctrl_impl::_set_atr_bits( - const size_t chan -) { - const auto rx_freq = radio_ctrl_impl::get_rx_frequency(chan); - const auto tx_freq = radio_ctrl_impl::get_tx_frequency(chan); - const auto rx_ant = radio_ctrl_impl::get_rx_antenna(chan); - const uint32_t rx_regs = _get_rx_switches(chan, rx_freq, rx_ant); - const uint32_t tx_regs = _get_tx_switches(chan, tx_freq); - const uint32_t idle_regs = TX_AMP_OFF << TX_AMP_SHIFT | - TRX1_SW_TX_HB << TRX_SW_SHIFT | - TX_SW2_LB_80 << TX_SW2_SHIFT | - TX_SW1_LB_80 << TX_SW1_SHIFT | - RX_SW3_OFF << RX_SW3_SHIFT | - RX_SW2_OFF << RX_SW2_SHIFT | - RX_SW1_OFF << RX_SW1_SHIFT; +void neon_radio_ctrl_impl::_set_atr_bits(const size_t chan) +{ + const auto rx_freq = radio_ctrl_impl::get_rx_frequency(chan); + const auto tx_freq = radio_ctrl_impl::get_tx_frequency(chan); + const auto rx_ant = radio_ctrl_impl::get_rx_antenna(chan); + const uint32_t rx_regs = _get_rx_switches(chan, rx_freq, rx_ant); + const uint32_t tx_regs = _get_tx_switches(chan, tx_freq); + const uint32_t idle_regs = TX_AMP_OFF << TX_AMP_SHIFT | TRX1_SW_TX_HB << TRX_SW_SHIFT + | TX_SW2_LB_80 << TX_SW2_SHIFT + | TX_SW1_LB_80 << TX_SW1_SHIFT | RX_SW3_OFF << RX_SW3_SHIFT + | RX_SW2_OFF << RX_SW2_SHIFT | RX_SW1_OFF << RX_SW1_SHIFT; _db_gpio[chan]->set_atr_reg(usrp::gpio_atr::ATR_REG_IDLE, idle_regs); _db_gpio[chan]->set_atr_reg(usrp::gpio_atr::ATR_REG_RX_ONLY, rx_regs); @@ -462,21 +414,21 @@ void neon_radio_ctrl_impl::_set_atr_bits( // The LED signal names are reversed, but are consistent with the schematic const int idle_led = 0; const bool is_txrx = rx_ant == "TX/RX"; - const int rx_led = 1 << TRX_LED_GRN_SHIFT; - const int tx_led = 1 << TX_LED_RED_SHIFT; + const int rx_led = 1 << TRX_LED_GRN_SHIFT; + const int tx_led = 1 << TX_LED_RED_SHIFT; const int txrx_led = 1 << RX_LED_GRN_SHIFT; _leds_gpio[chan]->set_atr_reg(usrp::gpio_atr::ATR_REG_IDLE, idle_led); - _leds_gpio[chan]->set_atr_reg(usrp::gpio_atr::ATR_REG_RX_ONLY, is_txrx ? txrx_led : rx_led); + _leds_gpio[chan]->set_atr_reg( + usrp::gpio_atr::ATR_REG_RX_ONLY, is_txrx ? txrx_led : rx_led); _leds_gpio[chan]->set_atr_reg(usrp::gpio_atr::ATR_REG_TX_ONLY, tx_led); _leds_gpio[chan]->set_atr_reg(usrp::gpio_atr::ATR_REG_FULL_DUPLEX, rx_led | tx_led); } -void neon_radio_ctrl_impl::_identify_with_leds( - const int identify_duration -) { - auto end_time = std::chrono::steady_clock::now() - + std::chrono::seconds(identify_duration); +void neon_radio_ctrl_impl::_identify_with_leds(const int identify_duration) +{ + auto end_time = + std::chrono::steady_clock::now() + std::chrono::seconds(identify_duration); bool led_state = true; while (std::chrono::steady_clock::now() < end_time) { // Add update_leds @@ -485,141 +437,126 @@ void neon_radio_ctrl_impl::_identify_with_leds( } } -uint32_t neon_radio_ctrl_impl::_get_tx_switches( - const size_t chan, - const double freq -) { - - UHD_LOG_TRACE(unique_id(), - "Update all TX freq related switches. f=" << freq << " Hz, " - ); +uint32_t neon_radio_ctrl_impl::_get_tx_switches(const size_t chan, const double freq) +{ + UHD_LOG_TRACE( + unique_id(), "Update all TX freq related switches. f=" << freq << " Hz, "); auto tx_sw1 = TX_SW1_LB_160; auto tx_sw2 = TX_SW2_LB_160; - auto trx_sw = (chan == 0) ? TRX1_SW_TX_LB: TRX2_SW_TX_LB; + auto trx_sw = (chan == 0) ? TRX1_SW_TX_LB : TRX2_SW_TX_LB; auto tx_amp = TX_AMP_LF_ON; const auto band = _map_freq_to_tx_band(freq); - switch(band) { - case tx_band::LB_80: - tx_sw1 = TX_SW1_LB_80; - tx_sw2 = TX_SW2_LB_80; - break; - case tx_band::LB_160: - tx_sw1 = TX_SW1_LB_160; - tx_sw2 = TX_SW2_LB_160; - break; - case tx_band::LB_225: - tx_sw1 = TX_SW1_LB_225; - tx_sw2 = TX_SW2_LB_225; - break; - case tx_band::LB_400: - tx_sw1 = TX_SW1_LB_400; - tx_sw2 = TX_SW2_LB_400; - break; - case tx_band::LB_575: - tx_sw1 = TX_SW1_LB_575; - tx_sw2 = TX_SW2_LB_575; - break; - case tx_band::LB_1000: - tx_sw1 = TX_SW1_LB_1000; - tx_sw2 = TX_SW2_LB_1000; - break; - case tx_band::LB_1700: - tx_sw1 = TX_SW1_LB_1700; - tx_sw2 = TX_SW2_LB_1700; - break; - case tx_band::LB_2750: - tx_sw1 = TX_SW1_LB_2750; - tx_sw2 = TX_SW2_LB_2750; - break; - case tx_band::HB: - trx_sw = (chan == 0) ? TRX1_SW_TX_HB: TRX2_SW_TX_HB; - tx_amp = TX_AMP_HF_ON; - break; - case tx_band::INVALID_BAND: - UHD_LOG_ERROR(unique_id(), - "Cannot map TX frequency to band: " << freq); - UHD_THROW_INVALID_CODE_PATH(); - break; + switch (band) { + case tx_band::LB_80: + tx_sw1 = TX_SW1_LB_80; + tx_sw2 = TX_SW2_LB_80; + break; + case tx_band::LB_160: + tx_sw1 = TX_SW1_LB_160; + tx_sw2 = TX_SW2_LB_160; + break; + case tx_band::LB_225: + tx_sw1 = TX_SW1_LB_225; + tx_sw2 = TX_SW2_LB_225; + break; + case tx_band::LB_400: + tx_sw1 = TX_SW1_LB_400; + tx_sw2 = TX_SW2_LB_400; + break; + case tx_band::LB_575: + tx_sw1 = TX_SW1_LB_575; + tx_sw2 = TX_SW2_LB_575; + break; + case tx_band::LB_1000: + tx_sw1 = TX_SW1_LB_1000; + tx_sw2 = TX_SW2_LB_1000; + break; + case tx_band::LB_1700: + tx_sw1 = TX_SW1_LB_1700; + tx_sw2 = TX_SW2_LB_1700; + break; + case tx_band::LB_2750: + tx_sw1 = TX_SW1_LB_2750; + tx_sw2 = TX_SW2_LB_2750; + break; + case tx_band::HB: + trx_sw = (chan == 0) ? TRX1_SW_TX_HB : TRX2_SW_TX_HB; + tx_amp = TX_AMP_HF_ON; + break; + case tx_band::INVALID_BAND: + UHD_LOG_ERROR(unique_id(), "Cannot map TX frequency to band: " << freq); + UHD_THROW_INVALID_CODE_PATH(); + break; } - auto tx_regs = tx_amp << TX_AMP_SHIFT | - trx_sw << TRX_SW_SHIFT | - tx_sw2 << TX_SW2_SHIFT | - tx_sw1 << TX_SW1_SHIFT; + auto tx_regs = tx_amp << TX_AMP_SHIFT | trx_sw << TRX_SW_SHIFT + | tx_sw2 << TX_SW2_SHIFT | tx_sw1 << TX_SW1_SHIFT; return tx_regs; } uint32_t neon_radio_ctrl_impl::_get_rx_switches( - const size_t chan, - const double freq, - const std::string &ant -){ - UHD_LOG_TRACE(unique_id(), - "Update all RX freq related switches. f=" << freq << " Hz, " - ); + const size_t chan, const double freq, const std::string& ant) +{ + UHD_LOG_TRACE( + unique_id(), "Update all RX freq related switches. f=" << freq << " Hz, "); // Default to OFF auto rx_sw1 = RX_SW1_OFF; auto rx_sw2 = RX_SW2_OFF; auto rx_sw3 = RX_SW3_OFF; - auto trx_sw = (chan == 0) ? TRX1_SW_RX: TRX2_SW_RX; + auto trx_sw = (chan == 0) ? TRX1_SW_RX : TRX2_SW_RX; if (ant == "TX/RX") { rx_sw3 = RX_SW3_HBRX_LBTRX; - trx_sw = (chan == 0) ? TRX1_SW_RX: TRX2_SW_RX; - } - else if (ant == "RX2") { + trx_sw = (chan == 0) ? TRX1_SW_RX : TRX2_SW_RX; + } else if (ant == "RX2") { rx_sw3 = RX_SW3_HBTRX_LBRX; // Set TRX switch to TX when receiving on RX2 trx_sw = TRX1_SW_TX_HB; } const auto band = _map_freq_to_rx_band(freq); - switch(band) { - case rx_band::LB_B2: - rx_sw1 = RX_SW1_LB_B2; - rx_sw2 = RX_SW2_LB_B2; - break; - case rx_band::LB_B3: - rx_sw1 = RX_SW1_LB_B3; - rx_sw2 = RX_SW2_LB_B3; - break; - case rx_band::LB_B4: - rx_sw1 = RX_SW1_LB_B4; - rx_sw2 = RX_SW2_LB_B4; - break; - case rx_band::LB_B5: - rx_sw1 = RX_SW1_LB_B5; - rx_sw2 = RX_SW2_LB_B5; - break; - case rx_band::LB_B6: - rx_sw1 = RX_SW1_LB_B6; - rx_sw2 = RX_SW2_LB_B6; - break; - case rx_band::LB_B7: - rx_sw1 = RX_SW1_LB_B7; - rx_sw2 = RX_SW2_LB_B7; - break; - case rx_band::HB: - rx_sw1 = RX_SW1_OFF; - rx_sw2 = RX_SW2_OFF; - if (ant == "TX/RX") { - rx_sw3 = RX_SW3_HBTRX_LBRX; - } - else if (ant == "RX2") { - rx_sw3 = RX_SW3_HBRX_LBTRX; - } - break; - case rx_band::INVALID_BAND: - UHD_LOG_ERROR(unique_id(), - "Cannot map RX frequency to band: " << freq); - UHD_THROW_INVALID_CODE_PATH(); - break; + switch (band) { + case rx_band::LB_B2: + rx_sw1 = RX_SW1_LB_B2; + rx_sw2 = RX_SW2_LB_B2; + break; + case rx_band::LB_B3: + rx_sw1 = RX_SW1_LB_B3; + rx_sw2 = RX_SW2_LB_B3; + break; + case rx_band::LB_B4: + rx_sw1 = RX_SW1_LB_B4; + rx_sw2 = RX_SW2_LB_B4; + break; + case rx_band::LB_B5: + rx_sw1 = RX_SW1_LB_B5; + rx_sw2 = RX_SW2_LB_B5; + break; + case rx_band::LB_B6: + rx_sw1 = RX_SW1_LB_B6; + rx_sw2 = RX_SW2_LB_B6; + break; + case rx_band::LB_B7: + rx_sw1 = RX_SW1_LB_B7; + rx_sw2 = RX_SW2_LB_B7; + break; + case rx_band::HB: + rx_sw1 = RX_SW1_OFF; + rx_sw2 = RX_SW2_OFF; + if (ant == "TX/RX") { + rx_sw3 = RX_SW3_HBTRX_LBRX; + } else if (ant == "RX2") { + rx_sw3 = RX_SW3_HBRX_LBTRX; + } + break; + case rx_band::INVALID_BAND: + UHD_LOG_ERROR(unique_id(), "Cannot map RX frequency to band: " << freq); + UHD_THROW_INVALID_CODE_PATH(); + break; } - auto rx_regs = trx_sw << TRX_SW_SHIFT | - rx_sw3 << RX_SW3_SHIFT | - rx_sw2 << RX_SW2_SHIFT | - rx_sw1 << RX_SW1_SHIFT; + auto rx_regs = trx_sw << TRX_SW_SHIFT | rx_sw3 << RX_SW3_SHIFT + | rx_sw2 << RX_SW2_SHIFT | rx_sw1 << RX_SW1_SHIFT; return rx_regs; } diff --git a/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.hpp index ac7fd70e9..88d1eed73 100644 --- a/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/neon/neon_radio_ctrl_impl.hpp @@ -11,13 +11,12 @@ #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <uhdlib/usrp/cores/gpio_atr_3000.hpp> -#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> #include <uhdlib/rfnoc/radio_ctrl_impl.hpp> +#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> +#include <uhdlib/usrp/cores/gpio_atr_3000.hpp> #include <mutex> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Provide access to an Magnesium radio. */ @@ -27,16 +26,7 @@ public: typedef boost::shared_ptr<neon_radio_ctrl_impl> sptr; //! Frequency bands for RX. Bands are a function of the analog filter banks - enum class rx_band { - INVALID_BAND, - LB_B2, - LB_B3, - LB_B4, - LB_B5, - LB_B6, - LB_B7, - HB - }; + enum class rx_band { INVALID_BAND, LB_B2, LB_B3, LB_B4, LB_B5, LB_B6, LB_B7, HB }; //! Frequency bands for TX. Bands are a function of the analog filter banks enum class tx_band { @@ -56,37 +46,28 @@ public: * ATR/ Switches Types *************************************************************************/ //! ATR state - enum atr_state_t { - IDLE, - RX_ONLY, - TX_ONLY, - FULL_DUPLEX - }; + enum atr_state_t { IDLE, RX_ONLY, TX_ONLY, FULL_DUPLEX }; //! Channel select: - enum chan_sel_t { - CHAN1, - CHAN2, - BOTH - }; + enum chan_sel_t { CHAN1, CHAN2, BOTH }; enum tx_sw1_t { - TX_SW1_LB_80 = 3, - TX_SW1_LB_160 = 7, - TX_SW1_LB_225 = 1, - TX_SW1_LB_400 = 5, - TX_SW1_LB_575 = 2, + TX_SW1_LB_80 = 3, + TX_SW1_LB_160 = 7, + TX_SW1_LB_225 = 1, + TX_SW1_LB_400 = 5, + TX_SW1_LB_575 = 2, TX_SW1_LB_1000 = 6, TX_SW1_LB_1700 = 0, TX_SW1_LB_2750 = 4 }; enum tx_sw2_t { - TX_SW2_LB_80 = 7, - TX_SW2_LB_160 = 3, - TX_SW2_LB_225 = 5, - TX_SW2_LB_400 = 1, - TX_SW2_LB_575 = 6, + TX_SW2_LB_80 = 7, + TX_SW2_LB_160 = 3, + TX_SW2_LB_225 = 5, + TX_SW2_LB_400 = 1, + TX_SW2_LB_575 = 6, TX_SW2_LB_1000 = 2, TX_SW2_LB_1700 = 4, TX_SW2_LB_2750 = 0 @@ -95,10 +76,10 @@ public: enum trx_sw_t { TRX1_SW_TX_HB = 2, TRX1_SW_TX_LB = 1, - TRX1_SW_RX = 4, + TRX1_SW_RX = 4, TRX2_SW_TX_HB = 2, TRX2_SW_TX_LB = 4, - TRX2_SW_RX = 1 + TRX2_SW_RX = 1 }; enum rx_sw1_t { @@ -108,7 +89,7 @@ public: RX_SW1_LB_B5 = 3, RX_SW1_LB_B6 = 0, RX_SW1_LB_B7 = 1, - RX_SW1_OFF = 7 + RX_SW1_OFF = 7 }; @@ -119,20 +100,16 @@ public: RX_SW2_LB_B5 = 2, RX_SW2_LB_B6 = 1, RX_SW2_LB_B7 = 0, - RX_SW2_OFF = 7 + RX_SW2_OFF = 7 }; enum rx_sw3_t { RX_SW3_HBRX_LBTRX = 1, RX_SW3_HBTRX_LBRX = 2, - RX_SW3_OFF = 0 //or 3 + RX_SW3_OFF = 0 // or 3 }; - enum tx_amp_t { - TX_AMP_HF_ON = 2, - TX_AMP_LF_ON = 1, - TX_AMP_OFF = 3 - }; + enum tx_amp_t { TX_AMP_HF_ON = 2, TX_AMP_LF_ON = 1, TX_AMP_OFF = 3 }; /************************************************************************ * Structors @@ -149,10 +126,11 @@ public: virtual bool check_radio_config(); //! Set which channel mode is used - void set_channel_mode(const std::string &channel_mode); + void set_channel_mode(const std::string& channel_mode); //! Set streaming mode - active chains, channel_mode, timing_mode - void set_streaming_mode(const bool tx1, const bool tx2, const bool rx1, const bool rx2); + void set_streaming_mode( + const bool tx1, const bool tx2, const bool rx1, const bool rx2); /*! Run a loopback self test. * @@ -163,19 +141,18 @@ public: * * \param iface An interface to the associated radio control core * \param iface The radio control core's address to write the loopback value - * \param iface The radio control core's readback address to read back the returned value + * \param iface The radio control core's readback address to read back the returned + * value * * \throws a uhd::runtime_error if the loopback value didn't match. */ - void loopback_self_test( - std::function<void(uint32_t)> poker_functor, - std::function<uint64_t()> peeker_functor - ); + void loopback_self_test(std::function<void(uint32_t)> poker_functor, + std::function<uint64_t()> peeker_functor); double set_rate(const double rate); - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); @@ -186,13 +163,10 @@ public: double set_tx_gain(const double gain, const size_t chan); double set_rx_gain(const double gain, const size_t chan); - size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir); + size_t get_chan_from_dboard_fe(const std::string& fe, const direction_t dir); std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir); - void set_rpc_client( - uhd::rpc_client::sptr rpcc, - const uhd::device_addr_t &block_args - ); + void set_rpc_client(uhd::rpc_client::sptr rpcc, const uhd::device_addr_t& block_args); private: /************************************************************************** @@ -205,10 +179,7 @@ private: void _init_defaults(); //! Init a subtree for the RF frontends - void _init_frontend_subtree( - uhd::property_tree::sptr subtree, - const size_t chan_idx - ); + void _init_frontend_subtree(uhd::property_tree::sptr subtree, const size_t chan_idx); //! Initialize Catalina defaults void _init_codec(); @@ -216,10 +187,7 @@ private: //! Initialize property tree void _init_prop_tree(); - void _init_mpm_sensors( - const direction_t dir, - const size_t chan_idx - ); + void _init_mpm_sensors(const direction_t dir, const size_t chan_idx); //! Map a frequency in Hz to an rx_band value. Will return // rx_band::INVALID_BAND if the frequency is out of range. @@ -233,33 +201,21 @@ private: *************************************************************************/ //! Return LO lock status. Factors in current band (low/high) and // direction (TX/RX) - bool get_lo_lock_status( - const direction_t dir - ); + bool get_lo_lock_status(const direction_t dir); /************************************************************************** * Misc Controls *************************************************************************/ //! Blink the front-panel LEDs for \p identify_duration, // and resume normal operation. - void _identify_with_leds( - const int identify_duration - ); + void _identify_with_leds(const int identify_duration); uint32_t _get_rx_switches( - const size_t chan, - const double freq, - const std::string &ant - ); + const size_t chan, const double freq, const std::string& ant); - uint32_t _get_tx_switches( - const size_t chan, - const double freq - ); + uint32_t _get_tx_switches(const size_t chan, const double freq); - void _set_atr_bits( - const size_t chan - ); + void _set_atr_bits(const size_t chan); /************************************************************************** * Private attributes @@ -283,7 +239,7 @@ private: uhd::spi_iface::sptr _spi; //! Reference to the AD9361 controls - //neon_ad9361_iface::uptr _ad9361; + // neon_ad9361_iface::uptr _ad9361; ad9361_ctrl::sptr _ad9361; //! ATR controls. These control the AD9361 gain @@ -305,4 +261,3 @@ private: }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_RFNOC_NEON_RADIO_CTRL_IMPL_HPP */ - diff --git a/host/lib/usrp/dboard/neon/neon_radio_ctrl_init.cpp b/host/lib/usrp/dboard/neon/neon_radio_ctrl_init.cpp index c71fd0169..783f0c7b2 100644 --- a/host/lib/usrp/dboard/neon/neon_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/neon/neon_radio_ctrl_init.cpp @@ -4,17 +4,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "neon_radio_ctrl_impl.hpp" #include "neon_constants.hpp" -#include <uhd/utils/log.hpp> +#include "neon_radio_ctrl_impl.hpp" +#include <uhd/transport/chdr.hpp> #include <uhd/types/eeprom.hpp> #include <uhd/types/sensors.hpp> -#include <uhd/transport/chdr.hpp> +#include <uhd/utils/log.hpp> #include <boost/algorithm/string.hpp> -#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/case_conv.hpp> -#include <vector> +#include <boost/algorithm/string/split.hpp> #include <string> +#include <vector> using namespace uhd; using namespace uhd::rfnoc; @@ -25,32 +25,35 @@ using namespace uhd::rfnoc; // This function convert the format of attribute "Radio_N_M" // to a single value port number = N*number_of_port_per_radio + M -uint32_t _extract_port_number(std::string radio_src_string, uhd::property_tree::sptr ptree){ +uint32_t _extract_port_number( + std::string radio_src_string, uhd::property_tree::sptr ptree) +{ std::string s_val = "0"; std::vector<std::string> radio_strings; - boost::algorithm::split( - radio_strings, + boost::algorithm::split(radio_strings, radio_src_string, boost::is_any_of("_/"), boost::token_compress_on); boost::to_lower(radio_strings[0]); - if (radio_strings.size()<3) { - throw uhd::runtime_error(str(boost::format("%s is an invalid GPIO source string.") % radio_src_string)); + if (radio_strings.size() < 3) { + throw uhd::runtime_error(str( + boost::format("%s is an invalid GPIO source string.") % radio_src_string)); } size_t radio_num = std::stoi(radio_strings[1]); - size_t port_num = std::stoi(radio_strings[2]); + size_t port_num = std::stoi(radio_strings[2]); if (radio_strings[0] != "radio") { - throw uhd::runtime_error("Front panel GPIO bank can only accept a radio block as its driver."); + throw uhd::runtime_error( + "Front panel GPIO bank can only accept a radio block as its driver."); } - std::string radio_port_out = "Radio_"+ radio_strings[1] + "/ports/out"; - std::string radio_port_path = radio_port_out + "/"+ radio_strings[2]; - auto found = ptree->exists(fs_path("xbar")/ radio_port_path); - if (not found){ - throw uhd::runtime_error(str(boost::format( - "Could not find radio port %s.\n") % radio_port_path)); + std::string radio_port_out = "Radio_" + radio_strings[1] + "/ports/out"; + std::string radio_port_path = radio_port_out + "/" + radio_strings[2]; + auto found = ptree->exists(fs_path("xbar") / radio_port_path); + if (not found) { + throw uhd::runtime_error( + str(boost::format("Could not find radio port %s.\n") % radio_port_path)); } - size_t port_size = ptree->list(fs_path("xbar")/ radio_port_out).size(); - return radio_num*port_size + port_num; + size_t port_size = ptree->list(fs_path("xbar") / radio_port_out).size(); + return radio_num * port_size + port_num; } void neon_radio_ctrl_impl::_init_defaults() @@ -60,8 +63,7 @@ void neon_radio_ctrl_impl::_init_defaults() const size_t num_tx_chans = get_input_ports().size(); UHD_LOG_TRACE(unique_id(), - "Num TX chans: " << num_tx_chans - << " Num RX chans: " << num_rx_chans); + "Num TX chans: " << num_tx_chans << " Num RX chans: " << num_rx_chans); for (size_t chan = 0; chan < num_rx_chans; chan++) { radio_ctrl_impl::set_rx_frequency(NEON_DEFAULT_FREQ, chan); @@ -83,8 +85,7 @@ void neon_radio_ctrl_impl::_init_defaults() const size_t default_spp = (_tree->access<size_t>("mtu/recv").get() - max_bytes_header) / (2 * sizeof(int16_t)); - UHD_LOG_DEBUG(unique_id(), - "Setting default spp to " << default_spp); + UHD_LOG_DEBUG(unique_id(), "Setting default spp to " << default_spp); _tree->access<int>(get_arg_path("spp") / "value").set(default_spp); } @@ -92,255 +93,181 @@ void neon_radio_ctrl_impl::_init_peripherals() { UHD_LOG_TRACE(unique_id(), "Initializing peripherals..."); - _db_gpio.clear(); // Following the as-if rule, this can get optimized out + _db_gpio.clear(); // Following the as-if rule, this can get optimized out for (size_t radio_idx = 0; radio_idx < _get_num_radios(); radio_idx++) { - UHD_LOG_TRACE(unique_id(), - "Initializing GPIOs for channel " << radio_idx); - _db_gpio.emplace_back( - usrp::gpio_atr::gpio_atr_3000::make_write_only( - _get_ctrl(radio_idx), - regs::sr_addr(regs::GPIO) - ) - ); - _db_gpio[radio_idx]->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); + UHD_LOG_TRACE(unique_id(), "Initializing GPIOs for channel " << radio_idx); + _db_gpio.emplace_back(usrp::gpio_atr::gpio_atr_3000::make_write_only( + _get_ctrl(radio_idx), regs::sr_addr(regs::GPIO))); + _db_gpio[radio_idx]->set_atr_mode( + usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); } - _leds_gpio.clear(); // Following the as-if rule, this can get optimized out + _leds_gpio.clear(); // Following the as-if rule, this can get optimized out for (size_t radio_idx = 0; radio_idx < _get_num_radios(); radio_idx++) { - UHD_LOG_TRACE(unique_id(), - "Initializing GPIOs for channel " << radio_idx); - _leds_gpio.emplace_back( - usrp::gpio_atr::gpio_atr_3000::make_write_only( - _get_ctrl(radio_idx), - regs::sr_addr(regs::LEDS) - ) - ); + UHD_LOG_TRACE(unique_id(), "Initializing GPIOs for channel " << radio_idx); + _leds_gpio.emplace_back(usrp::gpio_atr::gpio_atr_3000::make_write_only( + _get_ctrl(radio_idx), regs::sr_addr(regs::LEDS))); - _leds_gpio[radio_idx]->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); + _leds_gpio[radio_idx]->set_atr_mode( + usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); } UHD_LOG_TRACE(unique_id(), "Initializing front-panel GPIO control...") _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make( - _get_ctrl(0), - regs::sr_addr(regs::FP_GPIO), - regs::rb_addr(regs::RB_FP_GPIO) - ); + _get_ctrl(0), regs::sr_addr(regs::FP_GPIO), regs::rb_addr(regs::RB_FP_GPIO)); } void neon_radio_ctrl_impl::_init_frontend_subtree( - uhd::property_tree::sptr subtree, - const size_t chan_idx -) { + uhd::property_tree::sptr subtree, const size_t chan_idx) +{ const fs_path tx_fe_path = fs_path("tx_frontends") / chan_idx; const fs_path rx_fe_path = fs_path("rx_frontends") / chan_idx; UHD_LOG_TRACE(unique_id(), - "Adding non-RFNoC block properties for channel " << chan_idx << - " to prop tree path " << tx_fe_path << " and " << rx_fe_path); + "Adding non-RFNoC block properties for channel " + << chan_idx << " to prop tree path " << tx_fe_path << " and " << rx_fe_path); // TX Standard attributes - subtree->create<std::string>(tx_fe_path / "name") - .set(str(boost::format("Neon"))) - ; - subtree->create<std::string>(tx_fe_path / "connection") - .set("IQ") - ; + subtree->create<std::string>(tx_fe_path / "name").set(str(boost::format("Neon"))); + subtree->create<std::string>(tx_fe_path / "connection").set("IQ"); // RX Standard attributes - subtree->create<std::string>(rx_fe_path / "name") - .set(str(boost::format("Neon"))) - ; - subtree->create<std::string>(rx_fe_path / "connection") - .set("IQ") - ; + subtree->create<std::string>(rx_fe_path / "name").set(str(boost::format("Neon"))); + subtree->create<std::string>(rx_fe_path / "connection").set("IQ"); // TX Antenna subtree->create<std::string>(tx_fe_path / "antenna" / "value") - .add_coerced_subscriber([this, chan_idx](const std::string &ant){ + .add_coerced_subscriber([this, chan_idx](const std::string& ant) { this->set_tx_antenna(ant, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_tx_antenna(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_tx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(tx_fe_path / "antenna" / "options") .set({NEON_DEFAULT_TX_ANTENNA}) - .add_coerced_subscriber([](const std::vector<std::string> &){ - throw uhd::runtime_error( - "Attempting to update antenna options!"); - }) - ; + .add_coerced_subscriber([](const std::vector<std::string>&) { + throw uhd::runtime_error("Attempting to update antenna options!"); + }); // RX Antenna subtree->create<std::string>(rx_fe_path / "antenna" / "value") - .add_coerced_subscriber([this, chan_idx](const std::string &ant){ + .add_coerced_subscriber([this, chan_idx](const std::string& ant) { this->set_rx_antenna(ant, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_rx_antenna(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_rx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(rx_fe_path / "antenna" / "options") .set(NEON_RX_ANTENNAS) - .add_coerced_subscriber([](const std::vector<std::string> &){ - throw uhd::runtime_error( - "Attempting to update antenna options!"); - }) - ; + .add_coerced_subscriber([](const std::vector<std::string>&) { + throw uhd::runtime_error("Attempting to update antenna options!"); + }); // TX frequency subtree->create<double>(tx_fe_path / "freq" / "value") - .set_coercer([this, chan_idx](const double freq){ + .set_coercer([this, chan_idx](const double freq) { return this->set_tx_frequency(freq, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_tx_frequency(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_tx_frequency(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "freq" / "range") .set(meta_range_t(AD9361_TX_MIN_FREQ, AD9361_TX_MAX_FREQ, 1.0)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update freq range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update freq range!"); + }); // RX frequency subtree->create<double>(rx_fe_path / "freq" / "value") - .set_coercer([this, chan_idx](const double freq){ + .set_coercer([this, chan_idx](const double freq) { return this->set_rx_frequency(freq, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_rx_frequency(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_rx_frequency(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "freq" / "range") .set(meta_range_t(AD9361_RX_MIN_FREQ, AD9361_RX_MAX_FREQ, 1.0)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update freq range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update freq range!"); + }); // TX bandwidth subtree->create<double>(tx_fe_path / "bandwidth" / "value") .set(AD9361_TX_MAX_BANDWIDTH) - .set_coercer([this, chan_idx](const double bw){ + .set_coercer([this, chan_idx](const double bw) { return this->set_tx_bandwidth(bw, chan_idx); }) - .set_publisher([this, chan_idx](){ - return this->get_tx_bandwidth(chan_idx); - }) - ; + .set_publisher([this, chan_idx]() { return this->get_tx_bandwidth(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "bandwidth" / "range") .set(meta_range_t(AD9361_TX_MIN_BANDWIDTH, AD9361_TX_MAX_BANDWIDTH)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update bandwidth range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update bandwidth range!"); + }); // RX bandwidth subtree->create<double>(rx_fe_path / "bandwidth" / "value") .set(AD9361_RX_MAX_BANDWIDTH) - .set_coercer([this, chan_idx](const double bw){ + .set_coercer([this, chan_idx](const double bw) { return this->set_rx_bandwidth(bw, chan_idx); - }) - ; + }); subtree->create<meta_range_t>(rx_fe_path / "bandwidth" / "range") .set(meta_range_t(AD9361_RX_MIN_BANDWIDTH, AD9361_RX_MAX_BANDWIDTH)) - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update bandwidth range!"); - }) - ; + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update bandwidth range!"); + }); // TX gains const std::vector<std::string> tx_gain_names = ad9361_ctrl::get_gain_names("TX1"); for (auto tx_gain_name : tx_gain_names) { subtree->create<double>(tx_fe_path / "gains" / tx_gain_name / "value") - .set_coercer([this, chan_idx](const double gain){ + .set_coercer([this, chan_idx](const double gain) { return this->set_tx_gain(gain, chan_idx); }) - .set_publisher([this, chan_idx](){ - return radio_ctrl_impl::get_tx_gain(chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return radio_ctrl_impl::get_tx_gain(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "gains" / tx_gain_name / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ - return meta_range_t( - AD9361_MIN_TX_GAIN, - AD9361_MAX_TX_GAIN, - AD9361_TX_GAIN_STEP - ); - }) - ; + .set_publisher([this]() { + return meta_range_t( + AD9361_MIN_TX_GAIN, AD9361_MAX_TX_GAIN, AD9361_TX_GAIN_STEP); + }); } // RX gains const std::vector<std::string> rx_gain_names = ad9361_ctrl::get_gain_names("RX1"); for (auto rx_gain_name : rx_gain_names) { subtree->create<double>(rx_fe_path / "gains" / rx_gain_name / "value") - .set_coercer([this, chan_idx](const double gain){ + .set_coercer([this, chan_idx](const double gain) { return this->set_rx_gain(gain, chan_idx); }) - .set_publisher([this, chan_idx](){ - return radio_ctrl_impl::get_rx_gain(chan_idx); - }) - ; + .set_publisher( + [this, chan_idx]() { return radio_ctrl_impl::get_rx_gain(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "gains" / rx_gain_name / "range") - .add_coerced_subscriber([](const meta_range_t &){ - throw uhd::runtime_error( - "Attempting to update gain range!"); + .add_coerced_subscriber([](const meta_range_t&) { + throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this](){ + .set_publisher([this]() { return meta_range_t( - AD9361_MIN_RX_GAIN, - AD9361_MAX_RX_GAIN, - AD9361_RX_GAIN_STEP - ); - }) - ; + AD9361_MIN_RX_GAIN, AD9361_MAX_RX_GAIN, AD9361_RX_GAIN_STEP); + }); } // TX LO lock sensor ////////////////////////////////////////////////////// // Note: The AD9361 LO lock sensors are generated programmatically in // set_rpc_client(). The actual lo_locked publisher is also set there. subtree->create<sensor_value_t>(tx_fe_path / "sensors" / "lo_locked") - .set(sensor_value_t("all_los", false, "locked", "unlocked")) - .add_coerced_subscriber([](const sensor_value_t &){ - throw uhd::runtime_error( - "Attempting to write to sensor!"); + .set(sensor_value_t("all_los", false, "locked", "unlocked")) + .add_coerced_subscriber([](const sensor_value_t&) { + throw uhd::runtime_error("Attempting to write to sensor!"); }) - .set_publisher([this](){ + .set_publisher([this]() { return sensor_value_t( - "all_los", - this->get_lo_lock_status(TX_DIRECTION), - "locked", "unlocked" - ); - }) - ; + "all_los", this->get_lo_lock_status(TX_DIRECTION), "locked", "unlocked"); + }); // RX LO lock sensor (see not on TX LO lock sensor) subtree->create<sensor_value_t>(rx_fe_path / "sensors" / "lo_locked") - .set(sensor_value_t("all_los", false, "locked", "unlocked")) - .add_coerced_subscriber([](const sensor_value_t &){ - throw uhd::runtime_error( - "Attempting to write to sensor!"); + .set(sensor_value_t("all_los", false, "locked", "unlocked")) + .add_coerced_subscriber([](const sensor_value_t&) { + throw uhd::runtime_error("Attempting to write to sensor!"); }) - .set_publisher([this](){ + .set_publisher([this]() { return sensor_value_t( - "all_los", - this->get_lo_lock_status(RX_DIRECTION), - "locked", "unlocked" - ); - }) - ; + "all_los", this->get_lo_lock_status(RX_DIRECTION), "locked", "unlocked"); + }); } void neon_radio_ctrl_impl::_init_prop_tree() { const fs_path fe_base = fs_path("dboards") / _radio_slot; for (size_t chan_idx = 0; chan_idx < NEON_NUM_CHANS; chan_idx++) { - this->_init_frontend_subtree( - _tree->subtree(fe_base), chan_idx); + this->_init_frontend_subtree(_tree->subtree(fe_base), chan_idx); } - _tree->create<eeprom_map_t>(_root_path / "eeprom") - .set(eeprom_map_t()); + _tree->create<eeprom_map_t>(_root_path / "eeprom").set(eeprom_map_t()); _tree->create<int>("rx_codecs" / _radio_slot / "gains"); _tree->create<int>("tx_codecs" / _radio_slot / "gains"); @@ -349,98 +276,108 @@ void neon_radio_ctrl_impl::_init_prop_tree() if (not _tree->exists("tick_rate")) { _tree->create<double>("tick_rate") - .set_coercer([this](double tick_rate){ - return this->set_rate(tick_rate); - }) - .set_publisher([this](){ - return this->get_rate(); - }) - ; + .set_coercer([this](double tick_rate) { return this->set_rate(tick_rate); }) + .set_publisher([this]() { return this->get_rate(); }); } else { UHD_LOG_WARNING(unique_id(), "Cannot set tick_rate again"); } // *****FP_GPIO************************ - for(const auto& attr: usrp::gpio_atr::gpio_attr_map) { - if (not _tree->exists(fs_path("gpio") / "FP0" / attr.second)){ - switch (attr.first){ + for (const auto& attr : usrp::gpio_atr::gpio_attr_map) { + if (not _tree->exists(fs_path("gpio") / "FP0" / attr.second)) { + switch (attr.first) { case usrp::gpio_atr::GPIO_SRC: - //FIXME: move this creation of this branch of ptree out side of radio impl; - // since there's no data dependency between radio and SRC setting for FP0 - _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>( - 32, - usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr]( - const std::vector<std::string> str_val){ - uint32_t radio_src_value = 0; - uint32_t master_value = 0; - for(size_t i = 0 ; i<str_val.size(); i++){ - if(str_val[i] == "PS"){ - master_value += 1<<i;; - }else{ - auto port_num = _extract_port_number(str_val[i],_tree); - radio_src_value =(1<<(2*i))*port_num + radio_src_value; + // FIXME: move this creation of this branch of ptree out side of + // radio impl; + // since there's no data dependency between radio and SRC setting for + // FP0 + _tree + ->create<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t radio_src_value = 0; + uint32_t master_value = 0; + for (size_t i = 0; i < str_val.size(); i++) { + if (str_val[i] == "PS") { + master_value += 1 << i; + ; + } else { + auto port_num = + _extract_port_number(str_val[i], _tree); + radio_src_value = + (1 << (2 * i)) * port_num + radio_src_value; + } } - } - _rpcc->notify_with_token("set_fp_gpio_master", master_value); - _rpcc->notify_with_token("set_fp_gpio_radio_src", radio_src_value); - }); - break; + _rpcc->notify_with_token( + "set_fp_gpio_master", master_value); + _rpcc->notify_with_token( + "set_fp_gpio_radio_src", radio_src_value); + }); + break; case usrp::gpio_atr::GPIO_CTRL: case usrp::gpio_atr::GPIO_DDR: - _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>( - 32, - usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr]( - const std::vector<std::string> str_val){ - uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++){ - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i; - } - _fp_gpio->set_gpio_attr(attr.first, val); - }); + _tree + ->create<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t val = 0; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair + .at(attr.second) + .at(str_val[i]) + << i; + } + _fp_gpio->set_gpio_attr(attr.first, val); + }); break; - case usrp::gpio_atr::GPIO_READBACK:{ + case usrp::gpio_atr::GPIO_READBACK: { _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set_publisher([this](){ - return _fp_gpio->read_gpio(); - } - ); - } - break; + .set_publisher([this]() { return _fp_gpio->read_gpio(); }); + } break; default: _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set(0) - .add_coerced_subscriber([this, attr](const uint32_t val){ - _fp_gpio->set_gpio_attr(attr.first, val); - }); + .set(0) + .add_coerced_subscriber([this, attr](const uint32_t val) { + _fp_gpio->set_gpio_attr(attr.first, val); + }); } - }else{ - switch (attr.first){ + } else { + switch (attr.first) { case usrp::gpio_atr::GPIO_SRC: - break; + break; case usrp::gpio_atr::GPIO_CTRL: case usrp::gpio_atr::GPIO_DDR: - _tree->access<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr](const std::vector<std::string> str_val){ - uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++){ - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i; - } - _fp_gpio->set_gpio_attr(attr.first, val); - }); + _tree + ->access<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t val = 0; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair + .at(attr.second) + .at(str_val[i]) + << i; + } + _fp_gpio->set_gpio_attr(attr.first, val); + }); break; case usrp::gpio_atr::GPIO_READBACK: break; default: _tree->access<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set(0) - .add_coerced_subscriber([this, attr](const uint32_t val){ - _fp_gpio->set_gpio_attr(attr.first, val); - }); + .set(0) + .add_coerced_subscriber([this, attr](const uint32_t val) { + _fp_gpio->set_gpio_attr(attr.first, val); + }); } } } @@ -464,35 +401,27 @@ void neon_radio_ctrl_impl::_init_codec() } } -void neon_radio_ctrl_impl::_init_mpm_sensors( - const direction_t dir, - const size_t chan_idx -) { +void neon_radio_ctrl_impl::_init_mpm_sensors(const direction_t dir, const size_t chan_idx) +{ const std::string trx = (dir == RX_DIRECTION) ? "RX" : "TX"; - const fs_path fe_path = - fs_path("dboards") / _radio_slot / - (dir == RX_DIRECTION ? "rx_frontends" : "tx_frontends") / chan_idx; - auto sensor_list = - _rpcc->request_with_token<std::vector<std::string>>( - this->_rpc_prefix + "get_sensors", trx); + const fs_path fe_path = fs_path("dboards") / _radio_slot + / (dir == RX_DIRECTION ? "rx_frontends" : "tx_frontends") + / chan_idx; + auto sensor_list = _rpcc->request_with_token<std::vector<std::string>>( + this->_rpc_prefix + "get_sensors", trx); UHD_LOG_TRACE(unique_id(), - "Chan " << chan_idx << ": Found " - << sensor_list.size() << " " << trx << " sensors."); - for (const auto &sensor_name : sensor_list) { - UHD_LOG_TRACE(unique_id(), - "Adding " << trx << " sensor " << sensor_name); + "Chan " << chan_idx << ": Found " << sensor_list.size() << " " << trx + << " sensors."); + for (const auto& sensor_name : sensor_list) { + UHD_LOG_TRACE(unique_id(), "Adding " << trx << " sensor " << sensor_name); _tree->create<sensor_value_t>(fe_path / "sensors" / sensor_name) - .add_coerced_subscriber([](const sensor_value_t &){ - throw uhd::runtime_error( - "Attempting to write to sensor!"); + .add_coerced_subscriber([](const sensor_value_t&) { + throw uhd::runtime_error("Attempting to write to sensor!"); }) - .set_publisher([this, trx, sensor_name, chan_idx](){ + .set_publisher([this, trx, sensor_name, chan_idx]() { return sensor_value_t( this->_rpcc->request_with_token<sensor_value_t::sensor_map_t>( - this->_rpc_prefix + "get_sensor", - trx, sensor_name, chan_idx) - ); - }) - ; + this->_rpc_prefix + "get_sensor", trx, sensor_name, chan_idx)); + }); } } diff --git a/host/lib/usrp/dboard/neon/neon_regs.hpp b/host/lib/usrp/dboard/neon/neon_regs.hpp index 39ceca01c..d1ff940c6 100644 --- a/host/lib/usrp/dboard/neon/neon_regs.hpp +++ b/host/lib/usrp/dboard/neon/neon_regs.hpp @@ -10,17 +10,16 @@ #include <uhd/config.hpp> #include <cstdint> -static const uint32_t TX_AMP_SHIFT = 17; -static const uint32_t TRX_SW_SHIFT = 14; -static const uint32_t RX_SW1_SHIFT = 0; -static const uint32_t RX_SW2_SHIFT = 3; -static const uint32_t RX_SW3_SHIFT = 6; -static const uint32_t TX_SW1_SHIFT = 8; -static const uint32_t TX_SW2_SHIFT = 11; +static const uint32_t TX_AMP_SHIFT = 17; +static const uint32_t TRX_SW_SHIFT = 14; +static const uint32_t RX_SW1_SHIFT = 0; +static const uint32_t RX_SW2_SHIFT = 3; +static const uint32_t RX_SW3_SHIFT = 6; +static const uint32_t TX_SW1_SHIFT = 8; +static const uint32_t TX_SW2_SHIFT = 11; -static const uint32_t TRX_LED_GRN_SHIFT = 0; +static const uint32_t TRX_LED_GRN_SHIFT = 0; static const uint32_t TX_LED_RED_SHIFT = 1; static const uint32_t RX_LED_GRN_SHIFT = 2; #endif /* INCLUDED_NEON_REGS_HPP */ - diff --git a/host/lib/usrp/device3/device3_flow_ctrl.hpp b/host/lib/usrp/device3/device3_flow_ctrl.hpp index 50081543a..535d7fbac 100644 --- a/host/lib/usrp/device3/device3_flow_ctrl.hpp +++ b/host/lib/usrp/device3/device3_flow_ctrl.hpp @@ -8,10 +8,10 @@ #define INCLUDED_DEVICE3_FLOW_CTRL_HPP #include "device3_impl.hpp" -#include <uhd/utils/log.hpp> -#include <uhd/types/sid.hpp> -#include <uhd/transport/zero_copy.hpp> #include <uhd/transport/vrt_if_packet.hpp> +#include <uhd/transport/zero_copy.hpp> +#include <uhd/types/sid.hpp> +#include <uhd/utils/log.hpp> #include <boost/shared_ptr.hpp> namespace uhd { namespace usrp { @@ -19,12 +19,14 @@ namespace uhd { namespace usrp { //! Stores the state of RX flow control struct rx_fc_cache_t { - rx_fc_cache_t(): - interval(0), - last_byte_count(0), - total_bytes_consumed(0), - total_packets_consumed(0), - seq_num(0) {} + rx_fc_cache_t() + : interval(0) + , last_byte_count(0) + , total_bytes_consumed(0) + , total_packets_consumed(0) + , seq_num(0) + { + } //! Flow control interval in bytes size_t interval; @@ -40,117 +42,112 @@ struct rx_fc_cache_t uhd::transport::zero_copy_if::sptr xport; std::function<uint32_t(uint32_t)> to_host; std::function<uint32_t(uint32_t)> from_host; - std::function<void(const uint32_t *packet_buff, uhd::transport::vrt::if_packet_info_t &)> unpack; - std::function<void(uint32_t *packet_buff, uhd::transport::vrt::if_packet_info_t &)> pack; + std::function<void( + const uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)> + unpack; + std::function<void(uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)> + pack; }; /*! Send out RX flow control packets. -* -* This function handles updating the counters for the consumed -* bytes and packets, determines if a flow control message is -* is necessary, and sends one if it is. Passing a nullptr for -* the buff parameter will skip the counter update. -* -* \param fc_cache RX flow control state information -* \param buff Receive buffer. Setting to nullptr will -* skip the counter update. -*/ + * + * This function handles updating the counters for the consumed + * bytes and packets, determines if a flow control message is + * is necessary, and sends one if it is. Passing a nullptr for + * the buff parameter will skip the counter update. + * + * \param fc_cache RX flow control state information + * \param buff Receive buffer. Setting to nullptr will + * skip the counter update. + */ inline bool rx_flow_ctrl( - boost::shared_ptr<rx_fc_cache_t> fc_cache, - uhd::transport::managed_buffer::sptr buff -) { + boost::shared_ptr<rx_fc_cache_t> fc_cache, uhd::transport::managed_buffer::sptr buff) +{ // If the caller supplied a buffer - if (buff) - { + if (buff) { // Unpack the header uhd::transport::vrt::if_packet_info_t packet_info; - packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); - const uint32_t *pkt = buff->cast<const uint32_t *>(); + packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); + const uint32_t* pkt = buff->cast<const uint32_t*>(); try { fc_cache->unpack(pkt, packet_info); - } - catch(const std::exception &ex) - { + } catch (const std::exception& ex) { // Log and ignore - UHD_LOGGER_ERROR("RX FLOW CTRL") << "Error unpacking packet: " << ex.what() << std::endl; + UHD_LOGGER_ERROR("RX FLOW CTRL") + << "Error unpacking packet: " << ex.what() << std::endl; return true; } // Update counters assuming the buffer is a consumed packet - if (not packet_info.error) - { + if (not packet_info.error) { fc_cache->total_bytes_consumed += buff->size(); fc_cache->total_packets_consumed++; } } // Just return if there is no need to send a flow control packet - if (fc_cache->total_bytes_consumed - fc_cache->last_byte_count < fc_cache->interval) - { + if (fc_cache->total_bytes_consumed - fc_cache->last_byte_count < fc_cache->interval) { return true; } // Time to send a flow control packet // Get a send buffer - uhd::transport::managed_send_buffer::sptr fc_buff = fc_cache->xport->get_send_buff(0.0); + uhd::transport::managed_send_buffer::sptr fc_buff = + fc_cache->xport->get_send_buff(0.0); if (not fc_buff) { throw uhd::runtime_error("rx_flowctrl timed out getting a send buffer"); } - uint32_t *pkt = fc_buff->cast<uint32_t *>(); + uint32_t* pkt = fc_buff->cast<uint32_t*>(); - //load packet info + // load packet info uhd::transport::vrt::if_packet_info_t packet_info; packet_info.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_FC; packet_info.num_payload_words32 = uhd::usrp::DEVICE3_FC_PACKET_LEN_IN_WORDS32; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); - packet_info.packet_count = fc_cache->seq_num++; - packet_info.sob = false; - packet_info.eob = false; - packet_info.error = false; - packet_info.fc_ack = false; - packet_info.sid = fc_cache->sid.get(); - packet_info.has_sid = true; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = false; - packet_info.has_tlr = false; + packet_info.num_payload_bytes = packet_info.num_payload_words32 * sizeof(uint32_t); + packet_info.packet_count = fc_cache->seq_num++; + packet_info.sob = false; + packet_info.eob = false; + packet_info.error = false; + packet_info.fc_ack = false; + packet_info.sid = fc_cache->sid.get(); + packet_info.has_sid = true; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = false; + packet_info.has_tlr = false; // Load Header: fc_cache->pack(pkt, packet_info); // Load Payload: Packet count, and byte count - pkt[packet_info.num_header_words32+uhd::usrp::DEVICE3_FC_PACKET_COUNT_OFFSET] = + pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_PACKET_COUNT_OFFSET] = fc_cache->from_host(fc_cache->total_packets_consumed); - pkt[packet_info.num_header_words32+uhd::usrp::DEVICE3_FC_BYTE_COUNT_OFFSET] = + pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_BYTE_COUNT_OFFSET] = fc_cache->from_host(fc_cache->total_bytes_consumed); - //send the buffer over the interface - fc_buff->commit(sizeof(uint32_t)*(packet_info.num_packet_words32)); + // send the buffer over the interface + fc_buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32)); - //update byte count + // update byte count fc_cache->last_byte_count = fc_cache->total_bytes_consumed; return true; } /*! Handle RX flow control ACK packets. -* -*/ + * + */ inline void handle_rx_flowctrl_ack( - boost::shared_ptr<rx_fc_cache_t> fc_cache, - const uint32_t *payload -) { - const uint32_t pkt_count = fc_cache->to_host(payload[0]); + boost::shared_ptr<rx_fc_cache_t> fc_cache, const uint32_t* payload) +{ + const uint32_t pkt_count = fc_cache->to_host(payload[0]); const uint32_t byte_count = fc_cache->to_host(payload[1]); - if (fc_cache->total_bytes_consumed != byte_count) - { + if (fc_cache->total_bytes_consumed != byte_count) { UHD_LOGGER_DEBUG("device3") << "oh noes: byte_count==" << byte_count - << " total_bytes_consumed==" << fc_cache->total_bytes_consumed - << std::hex << " sid==" << fc_cache->sid << std::dec - << std::endl - ; + << " total_bytes_consumed==" << fc_cache->total_bytes_consumed << std::hex + << " sid==" << fc_cache->sid << std::dec << std::endl; } - fc_cache->total_bytes_consumed = byte_count; + fc_cache->total_bytes_consumed = byte_count; fc_cache->total_packets_consumed = pkt_count; // guess we need a pkt offset too? // This will send a flow control packet if there is a significant discrepancy @@ -160,14 +157,16 @@ inline void handle_rx_flowctrl_ack( //! Stores the state of TX flow control struct tx_fc_cache_t { - tx_fc_cache_t(uint32_t capacity): - last_byte_ack(0), - last_seq_ack(0), - byte_count(0), - pkt_count(0), - window_size(capacity), - fc_ack_seqnum(0), - fc_received(false) {} + tx_fc_cache_t(uint32_t capacity) + : last_byte_ack(0) + , last_seq_ack(0) + , byte_count(0) + , pkt_count(0) + , window_size(capacity) + , fc_ack_seqnum(0) + , fc_received(false) + { + } uint32_t last_byte_ack; uint32_t last_seq_ack; @@ -178,26 +177,28 @@ struct tx_fc_cache_t bool fc_received; std::function<uint32_t(uint32_t)> to_host; std::function<uint32_t(uint32_t)> from_host; - std::function<void(const uint32_t *packet_buff, uhd::transport::vrt::if_packet_info_t &)> unpack; - std::function<void(uint32_t *packet_buff, uhd::transport::vrt::if_packet_info_t &)> pack; + std::function<void( + const uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)> + unpack; + std::function<void(uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)> + pack; }; -inline bool tx_flow_ctrl( - boost::shared_ptr<tx_fc_cache_t> fc_cache, +inline bool tx_flow_ctrl(boost::shared_ptr<tx_fc_cache_t> fc_cache, uhd::transport::zero_copy_if::sptr xport, - uhd::transport::managed_buffer::sptr buff -) { - while (true) - { + uhd::transport::managed_buffer::sptr buff) +{ + while (true) { // If there is space - if (fc_cache->window_size - (fc_cache->byte_count - fc_cache->last_byte_ack) >= buff->size()) - { + if (fc_cache->window_size - (fc_cache->byte_count - fc_cache->last_byte_ack) + >= buff->size()) { // All is good - packet will be sent fc_cache->byte_count += buff->size(); // Round up to nearest word - if (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE) - { - fc_cache->byte_count += uhd::usrp::DEVICE3_LINE_SIZE - (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE); + if (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE) { + fc_cache->byte_count += + uhd::usrp::DEVICE3_LINE_SIZE + - (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE); } fc_cache->pkt_count++; return true; @@ -205,33 +206,33 @@ inline bool tx_flow_ctrl( // Look for a flow control message to update the space available in the buffer. uhd::transport::managed_recv_buffer::sptr buff = xport->get_recv_buff(0.1); - if (buff) - { + if (buff) { uhd::transport::vrt::if_packet_info_t if_packet_info; - if_packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); - const uint32_t *packet_buff = buff->cast<const uint32_t *>(); + if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); + const uint32_t* packet_buff = buff->cast<const uint32_t*>(); try { fc_cache->unpack(packet_buff, if_packet_info); - } - catch(const std::exception &ex) - { - UHD_LOGGER_ERROR("TX FLOW CTRL") << "Error unpacking flow control packet: " << ex.what() << std::endl; + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("TX FLOW CTRL") + << "Error unpacking flow control packet: " << ex.what() << std::endl; continue; } - if (if_packet_info.packet_type != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_FC) - { - UHD_LOGGER_ERROR("TX FLOW CTRL") << "Unexpected packet received by flow control handler: " << if_packet_info.packet_type << std::endl; + if (if_packet_info.packet_type + != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_FC) { + UHD_LOGGER_ERROR("TX FLOW CTRL") + << "Unexpected packet received by flow control handler: " + << if_packet_info.packet_type << std::endl; continue; } - const uint32_t *payload = &packet_buff[if_packet_info.num_header_words32]; - const uint32_t pkt_count = fc_cache->to_host(payload[0]); + const uint32_t* payload = &packet_buff[if_packet_info.num_header_words32]; + const uint32_t pkt_count = fc_cache->to_host(payload[0]); const uint32_t byte_count = fc_cache->to_host(payload[1]); // update the amount of space fc_cache->last_byte_ack = byte_count; - fc_cache->last_seq_ack = pkt_count; + fc_cache->last_seq_ack = pkt_count; fc_cache->fc_received = true; } @@ -239,13 +240,11 @@ inline bool tx_flow_ctrl( return false; } -inline void tx_flow_ctrl_ack( - boost::shared_ptr<tx_fc_cache_t> fc_cache, +inline void tx_flow_ctrl_ack(boost::shared_ptr<tx_fc_cache_t> fc_cache, uhd::transport::zero_copy_if::sptr send_xport, - uhd::sid_t send_sid -) { - if (not fc_cache->fc_received) - { + uhd::sid_t send_sid) +{ + if (not fc_cache->fc_received) { return; } @@ -256,42 +255,42 @@ inline void tx_flow_ctrl_ack( UHD_LOGGER_ERROR("tx_flow_ctrl_ack") << "timed out getting a send buffer"; return; } - uint32_t *pkt = fc_buff->cast<uint32_t *>(); + uint32_t* pkt = fc_buff->cast<uint32_t*>(); // Load packet info uhd::transport::vrt::if_packet_info_t packet_info; packet_info.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_ACK; packet_info.num_payload_words32 = uhd::usrp::DEVICE3_FC_PACKET_LEN_IN_WORDS32; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); - packet_info.packet_count = fc_cache->fc_ack_seqnum++; - packet_info.sob = false; - packet_info.eob = true; - packet_info.error = false; - packet_info.fc_ack = false; - packet_info.sid = send_sid.get(); - packet_info.has_sid = true; - packet_info.has_cid = false; - packet_info.has_tsi = false; - packet_info.has_tsf = false; - packet_info.has_tlr = false; + packet_info.num_payload_bytes = packet_info.num_payload_words32 * sizeof(uint32_t); + packet_info.packet_count = fc_cache->fc_ack_seqnum++; + packet_info.sob = false; + packet_info.eob = true; + packet_info.error = false; + packet_info.fc_ack = false; + packet_info.sid = send_sid.get(); + packet_info.has_sid = true; + packet_info.has_cid = false; + packet_info.has_tsi = false; + packet_info.has_tsf = false; + packet_info.has_tlr = false; // Load Header: fc_cache->pack(pkt, packet_info); // Update counters to include this packet - size_t fc_ack_pkt_size = sizeof(uint32_t)*(packet_info.num_packet_words32); + size_t fc_ack_pkt_size = sizeof(uint32_t) * (packet_info.num_packet_words32); fc_cache->byte_count += fc_ack_pkt_size; // Round up to nearest word - if (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE) - { - fc_cache->byte_count += uhd::usrp::DEVICE3_LINE_SIZE - (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE); + if (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE) { + fc_cache->byte_count += uhd::usrp::DEVICE3_LINE_SIZE + - (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE); } fc_cache->pkt_count++; // Load Payload: Packet count, and byte count - pkt[packet_info.num_header_words32+uhd::usrp::DEVICE3_FC_PACKET_COUNT_OFFSET] = + pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_PACKET_COUNT_OFFSET] = fc_cache->from_host(fc_cache->pkt_count); - pkt[packet_info.num_header_words32+uhd::usrp::DEVICE3_FC_BYTE_COUNT_OFFSET] = + pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_BYTE_COUNT_OFFSET] = fc_cache->from_host(fc_cache->byte_count); // Send the buffer over the interface @@ -301,6 +300,6 @@ inline void tx_flow_ctrl_ack( fc_cache->fc_received = false; } -}}; +}}; // namespace uhd::usrp #endif /* INCLUDED_DEVICE3_FLOW_CTRL_HPP */ diff --git a/host/lib/usrp/device3/device3_impl.cpp b/host/lib/usrp/device3/device3_impl.cpp index 5705d6a84..d636b3338 100644 --- a/host/lib/usrp/device3/device3_impl.cpp +++ b/host/lib/usrp/device3/device3_impl.cpp @@ -6,10 +6,10 @@ // #include "device3_impl.hpp" -#include <uhd/utils/log.hpp> #include <uhd/rfnoc/block_ctrl_base.hpp> -#include <uhdlib/rfnoc/graph_impl.hpp> +#include <uhd/utils/log.hpp> #include <uhdlib/rfnoc/ctrl_iface.hpp> +#include <uhdlib/rfnoc/graph_impl.hpp> #include <boost/make_shared.hpp> #include <algorithm> @@ -18,21 +18,20 @@ using namespace uhd::usrp; device3_impl::device3_impl() { _type = uhd::device::USRP; - _async_md.reset(new async_md_type(1000/*messages deep*/)); + _async_md.reset(new async_md_type(1000 /*messages deep*/)); _tree = uhd::property_tree::make(); }; //! Returns true if the integer value stored in lhs is smaller than that in rhs -bool _compare_string_indexes(const std::string &lhs, const std::string &rhs) +bool _compare_string_indexes(const std::string& lhs, const std::string& rhs) { return boost::lexical_cast<size_t>(lhs) < boost::lexical_cast<size_t>(rhs); } -void device3_impl::merge_channel_defs( - const std::vector<uhd::rfnoc::block_id_t> &chan_ids, - const std::vector<uhd::device_addr_t> &chan_args, - const uhd::direction_t dir -) { +void device3_impl::merge_channel_defs(const std::vector<uhd::rfnoc::block_id_t>& chan_ids, + const std::vector<uhd::device_addr_t>& chan_args, + const uhd::direction_t dir) +{ UHD_ASSERT_THROW(chan_ids.size() == chan_args.size()); if (dir == uhd::DX_DIRECTION) { merge_channel_defs(chan_ids, chan_args, RX_DIRECTION); @@ -40,7 +39,8 @@ void device3_impl::merge_channel_defs( return; } - uhd::fs_path chans_root = uhd::fs_path("/channels/") / (dir == RX_DIRECTION ? "rx" : "tx"); + uhd::fs_path chans_root = + uhd::fs_path("/channels/") / (dir == RX_DIRECTION ? "rx" : "tx"); // Store the new positions of the channels: std::vector<size_t> chan_idxs; @@ -54,18 +54,23 @@ void device3_impl::merge_channel_defs( // 2. Cycle through existing channels to find out where to merge // the new channels. Rules are: // - The order of chan_ids must be preserved - // - All block indices that are in chan_ids may be overwritten in the channel definition + // - All block indices that are in chan_ids may be overwritten in the channel + // definition // - If the channels in chan_ids are not yet in the property tree channel list, // they are appended. - for(const std::string &chan_idx: curr_channels) { + for (const std::string& chan_idx : curr_channels) { if (_tree->exists(chans_root / chan_idx)) { - rfnoc::block_id_t chan_block_id = _tree->access<rfnoc::block_id_t>(chans_root / chan_idx).get(); - if (std::find(chan_ids.begin(), chan_ids.end(), chan_block_id) != chan_ids.end()) { + rfnoc::block_id_t chan_block_id = + _tree->access<rfnoc::block_id_t>(chans_root / chan_idx).get(); + if (std::find(chan_ids.begin(), chan_ids.end(), chan_block_id) + != chan_ids.end()) { chan_idxs.push_back(boost::lexical_cast<size_t>(chan_idx)); } } } - size_t last_chan_idx = curr_channels.empty() ? 0 : (boost::lexical_cast<size_t>(curr_channels.back()) + 1); + size_t last_chan_idx = curr_channels.empty() + ? 0 + : (boost::lexical_cast<size_t>(curr_channels.back()) + 1); while (chan_idxs.size() < chan_ids.size()) { chan_idxs.push_back(last_chan_idx); last_chan_idx++; @@ -80,27 +85,28 @@ void device3_impl::merge_channel_defs( if (not _tree->exists(chans_root / chan_idxs[i] / "args")) { _tree->create<uhd::device_addr_t>(chans_root / chan_idxs[i] / "args"); } - _tree->access<uhd::device_addr_t>(chans_root / chan_idxs[i] / "args").set(chan_args[i]); + _tree->access<uhd::device_addr_t>(chans_root / chan_idxs[i] / "args") + .set(chan_args[i]); } } /*********************************************************************** * RFNoC-Specific **********************************************************************/ -void device3_impl::enumerate_rfnoc_blocks( - size_t device_index, - size_t n_blocks, - size_t base_port, - const uhd::sid_t &base_sid, - uhd::device_addr_t transport_args -) { +void device3_impl::enumerate_rfnoc_blocks(size_t device_index, + size_t n_blocks, + size_t base_port, + const uhd::sid_t& base_sid, + uhd::device_addr_t transport_args) +{ // entries that are already connected to this block uhd::sid_t ctrl_sid = base_sid; - uhd::property_tree::sptr subtree = _tree->subtree(uhd::fs_path("/mboards") / device_index); + uhd::property_tree::sptr subtree = + _tree->subtree(uhd::fs_path("/mboards") / device_index); // 1) Clean property tree entries // TODO put this back once radios are actual rfnoc blocks!!!!!! - //if (subtree->exists("xbar")) { - //subtree->remove("xbar"); + // if (subtree->exists("xbar")) { + // subtree->remove("xbar"); //} // 2) Destroy existing block controllers // TODO: Clear out all the old block control classes @@ -109,40 +115,27 @@ void device3_impl::enumerate_rfnoc_blocks( // First, make a transport for port number zero, because we always need that: ctrl_sid.set_dst_xbarport(base_port + i); ctrl_sid.set_dst_blockport(0); - both_xports_t xport = this->make_transport( - ctrl_sid, - CTRL, - transport_args - ); + both_xports_t xport = this->make_transport(ctrl_sid, CTRL, transport_args); UHD_LOG_TRACE("DEVICE3", str(boost::format("Setting up NoC-Shell Control for port #0 (SID: %s)...") - % xport.send_sid.to_pp_string_hex()) - ); - uhd::rfnoc::ctrl_iface::sptr ctrl = uhd::rfnoc::ctrl_iface::make( - xport, - str(boost::format("CE_%02d_Port_%02X") - % i - % ctrl_sid.get_dst_endpoint()) - ); - uint64_t noc_id = ctrl->send_cmd_pkt( - uhd::rfnoc::SR_READBACK, - uhd::rfnoc::SR_READBACK_REG_ID, - true - ); - UHD_LOG_DEBUG("DEVICE3", str( - boost::format("Port 0x%02X: Found NoC-Block with ID %016X.") - % int(ctrl_sid.get_dst_endpoint()) - % noc_id - )); + % xport.send_sid.to_pp_string_hex())); + uhd::rfnoc::ctrl_iface::sptr ctrl = uhd::rfnoc::ctrl_iface::make(xport, + str(boost::format("CE_%02d_Port_%02X") % i % ctrl_sid.get_dst_endpoint())); + uint64_t noc_id = ctrl->send_cmd_pkt( + uhd::rfnoc::SR_READBACK, uhd::rfnoc::SR_READBACK_REG_ID, true); + UHD_LOG_DEBUG("DEVICE3", + str(boost::format("Port 0x%02X: Found NoC-Block with ID %016X.") + % int(ctrl_sid.get_dst_endpoint()) % noc_id)); uhd::rfnoc::make_args_t make_args; - uhd::rfnoc::blockdef::sptr block_def = uhd::rfnoc::blockdef::make_from_noc_id(noc_id); + uhd::rfnoc::blockdef::sptr block_def = + uhd::rfnoc::blockdef::make_from_noc_id(noc_id); if (not block_def) { UHD_LOG_WARNING("DEVICE3", "No block definition found, using default block configuration " - "for block with NOC ID: " + str(boost::format("0x%08X") % noc_id) - ); - block_def = uhd::rfnoc::blockdef::make_from_noc_id( - uhd::rfnoc::DEFAULT_NOC_ID); + "for block with NOC ID: " + + str(boost::format("0x%08X") % noc_id)); + block_def = + uhd::rfnoc::blockdef::make_from_noc_id(uhd::rfnoc::DEFAULT_NOC_ID); } UHD_ASSERT_THROW(block_def); make_args.ctrl_ifaces[0] = ctrl; @@ -151,71 +144,59 @@ void device3_impl::enumerate_rfnoc_blocks( continue; } ctrl_sid.set_dst_blockport(port_number); - both_xports_t xport1 = this->make_transport( - ctrl_sid, - CTRL, - transport_args - ); - UHD_LOG_TRACE("DEVICE3", str( - boost::format("Setting up NoC-Shell Control for port #%d " + both_xports_t xport1 = this->make_transport(ctrl_sid, CTRL, transport_args); + UHD_LOG_TRACE("DEVICE3", + str(boost::format("Setting up NoC-Shell Control for port #%d " "(SID: %s)...") - % port_number - % xport1.send_sid.to_pp_string_hex() - )); - uhd::rfnoc::ctrl_iface::sptr ctrl1 = uhd::rfnoc::ctrl_iface::make( - xport1, - str(boost::format("CE_%02d_Port_%02X") % i % ctrl_sid.get_dst_endpoint()) - ); + % port_number % xport1.send_sid.to_pp_string_hex())); + uhd::rfnoc::ctrl_iface::sptr ctrl1 = uhd::rfnoc::ctrl_iface::make(xport1, + str(boost::format("CE_%02d_Port_%02X") % i + % ctrl_sid.get_dst_endpoint())); make_args.ctrl_ifaces[port_number] = ctrl1; } UHD_LOG_TRACE("DEVICE3", - "All control transports successfully created for block with ID " << - str(boost::format("0x%08X") % noc_id) - ); + "All control transports successfully created for block with ID " + << str(boost::format("0x%08X") % noc_id)); make_args.base_address = xport.send_sid.get_dst(); make_args.device_index = device_index; - make_args.tree = subtree; - { //Critical section for block_ctrl vector access + make_args.tree = subtree; + { // Critical section for block_ctrl vector access boost::lock_guard<boost::mutex> lock(_block_ctrl_mutex); - _rfnoc_block_ctrl.push_back(uhd::rfnoc::block_ctrl_base::make(make_args, noc_id)); + _rfnoc_block_ctrl.push_back( + uhd::rfnoc::block_ctrl_base::make(make_args, noc_id)); } } } -uhd::rfnoc::graph::sptr device3_impl::create_graph(const std::string &name) +uhd::rfnoc::graph::sptr device3_impl::create_graph(const std::string& name) { // Create an async message handler - UHD_LOGGER_TRACE("DEVICE3") << "Creating async message handler for graph `" << name << "'..."; - // FIXME: right now this only can only handle source sid of 0 and xbar local addr of 2. - // This is ok for now because that most of our device has xbard local addr hardcode to 2. + UHD_LOGGER_TRACE("DEVICE3") + << "Creating async message handler for graph `" << name << "'..."; + // FIXME: right now this only can only handle source sid of 0 and xbar local addr + // of 2. This is ok for now because that most of our device has xbard local addr + // hardcode to 2. sid_t async_sid(0); async_sid.set_dst_addr(2); - both_xports_t async_xports = make_transport( - async_sid, - ASYNC_MSG, - //FIXME: only get rx_hints from mb index of 0 - get_rx_hints(0) - ); + both_xports_t async_xports = make_transport(async_sid, + ASYNC_MSG, + // FIXME: only get rx_hints from mb index of 0 + get_rx_hints(0)); UHD_LOGGER_TRACE("DEVICE3") << " Async transport ready." << std::endl; uhd::rfnoc::async_msg_handler::sptr async_msg_handler = - uhd::rfnoc::async_msg_handler::make( - async_xports.recv, - async_xports.send, - async_xports.send_sid, - async_xports.endianness - ); - UHD_LOGGER_TRACE("DEVICE3") << "Async message has address " << async_xports.send_sid << std::endl; + uhd::rfnoc::async_msg_handler::make(async_xports.recv, + async_xports.send, + async_xports.send_sid, + async_xports.endianness); + UHD_LOGGER_TRACE("DEVICE3") + << "Async message has address " << async_xports.send_sid << std::endl; // Create the graph UHD_LOGGER_TRACE("DEVICE3") << "Creating graph `" << name << "'..." << std::endl; uhd::rfnoc::graph::sptr graph = boost::make_shared<uhd::rfnoc::graph_impl>( - name, - shared_from_this(), - async_msg_handler - ); + name, shared_from_this(), async_msg_handler); return graph; } - diff --git a/host/lib/usrp/device3/device3_impl.hpp b/host/lib/usrp/device3/device3_impl.hpp index e82597b9b..3bf6f6111 100644 --- a/host/lib/usrp/device3/device3_impl.hpp +++ b/host/lib/usrp/device3/device3_impl.hpp @@ -11,20 +11,20 @@ #ifndef INCLUDED_DEVICE3_IMPL_HPP #define INCLUDED_DEVICE3_IMPL_HPP +#include "../../transport/super_recv_packet_handler.hpp" +#include "../../transport/super_send_packet_handler.hpp" +#include <uhd/device3.hpp> #include <uhd/transport/bounded_buffer.hpp> -#include <uhd/transport/vrt_if_packet.hpp> #include <uhd/transport/chdr.hpp> +#include <uhd/transport/vrt_if_packet.hpp> #include <uhd/transport/zero_copy.hpp> -#include <uhd/types/sid.hpp> -#include <uhd/types/metadata.hpp> -#include <uhd/types/endianness.hpp> #include <uhd/types/direction.hpp> +#include <uhd/types/endianness.hpp> +#include <uhd/types/metadata.hpp> +#include <uhd/types/sid.hpp> #include <uhd/utils/tasks.hpp> -#include <uhd/device3.hpp> -#include "../../transport/super_send_packet_handler.hpp" -#include "../../transport/super_recv_packet_handler.hpp" -#include <uhdlib/rfnoc/tx_stream_terminator.hpp> #include <uhdlib/rfnoc/rx_stream_terminator.hpp> +#include <uhdlib/rfnoc/tx_stream_terminator.hpp> #include <uhdlib/rfnoc/xports.hpp> namespace uhd { namespace usrp { @@ -32,31 +32,33 @@ namespace uhd { namespace usrp { /*********************************************************************** * Default settings (any device3 may override these) **********************************************************************/ -static const size_t DEVICE3_RX_FC_REQUEST_FREQ = 32; //per flow-control window -static const size_t DEVICE3_TX_FC_RESPONSE_FREQ = 8; -static const size_t DEVICE3_FC_PACKET_LEN_IN_WORDS32 = 2; -static const size_t DEVICE3_FC_PACKET_COUNT_OFFSET = 0; -static const size_t DEVICE3_FC_BYTE_COUNT_OFFSET = 1; -static const size_t DEVICE3_LINE_SIZE = 8; - -static const size_t DEVICE3_TX_MAX_HDR_LEN = uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); // Bytes -static const size_t DEVICE3_RX_MAX_HDR_LEN = uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); // Bytes - -// This class manages the lifetime of the TX async message handler task, transports, and terminator +static const size_t DEVICE3_RX_FC_REQUEST_FREQ = 32; // per flow-control window +static const size_t DEVICE3_TX_FC_RESPONSE_FREQ = 8; +static const size_t DEVICE3_FC_PACKET_LEN_IN_WORDS32 = 2; +static const size_t DEVICE3_FC_PACKET_COUNT_OFFSET = 0; +static const size_t DEVICE3_FC_BYTE_COUNT_OFFSET = 1; +static const size_t DEVICE3_LINE_SIZE = 8; + +static const size_t DEVICE3_TX_MAX_HDR_LEN = + uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); // Bytes +static const size_t DEVICE3_RX_MAX_HDR_LEN = + uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); // Bytes + +// This class manages the lifetime of the TX async message handler task, transports, and +// terminator class device3_send_packet_streamer : public uhd::transport::sph::send_packet_streamer { public: - device3_send_packet_streamer( - const size_t max_num_samps, - const uhd::rfnoc::tx_stream_terminator::sptr terminator, - const both_xports_t data_xport, - const both_xports_t async_msg_xport - ) : - uhd::transport::sph::send_packet_streamer(max_num_samps), - _terminator(terminator), - _data_xport(data_xport), - _async_msg_xport(async_msg_xport) - {} + device3_send_packet_streamer(const size_t max_num_samps, + const uhd::rfnoc::tx_stream_terminator::sptr terminator, + const both_xports_t data_xport, + const both_xports_t async_msg_xport) + : uhd::transport::sph::send_packet_streamer(max_num_samps) + , _terminator(terminator) + , _data_xport(data_xport) + , _async_msg_xport(async_msg_xport) + { + } ~device3_send_packet_streamer() { @@ -81,18 +83,19 @@ private: std::vector<task::sptr> _tx_async_msg_tasks; }; -// This class manages the lifetime of the RX transports and terminator and provides access to both +// This class manages the lifetime of the RX transports and terminator and provides access +// to both class device3_recv_packet_streamer : public uhd::transport::sph::recv_packet_streamer { public: - device3_recv_packet_streamer( - const size_t max_num_samps, - const uhd::rfnoc::rx_stream_terminator::sptr terminator, - const both_xports_t xport - ) : - uhd::transport::sph::recv_packet_streamer(max_num_samps), - _terminator(terminator), - _xport(xport) {} + device3_recv_packet_streamer(const size_t max_num_samps, + const uhd::rfnoc::rx_stream_terminator::sptr terminator, + const both_xports_t xport) + : uhd::transport::sph::recv_packet_streamer(max_num_samps) + , _terminator(terminator) + , _xport(xport) + { + } ~device3_recv_packet_streamer() {} @@ -111,7 +114,8 @@ private: both_xports_t _xport; }; -class device3_impl : public uhd::device3, public boost::enable_shared_from_this<device3_impl> +class device3_impl : public uhd::device3, + public boost::enable_shared_from_this<device3_impl> { public: /*********************************************************************** @@ -120,14 +124,9 @@ public: typedef uhd::transport::bounded_buffer<uhd::async_metadata_t> async_md_type; //! The purpose of a transport - enum xport_type_t { - CTRL = 0, - ASYNC_MSG, - TX_DATA, - RX_DATA - }; + enum xport_type_t { CTRL = 0, ASYNC_MSG, TX_DATA, RX_DATA }; - enum xport_t {AXI, ETH, PCIE}; + enum xport_t { AXI, ETH, PCIE }; //! Stores all streaming-related options struct stream_options_t @@ -145,20 +144,21 @@ public: , rx_max_len_hdr(DEVICE3_RX_MAX_HDR_LEN) , rx_fc_request_freq(DEVICE3_RX_FC_REQUEST_FREQ) , tx_fc_response_freq(DEVICE3_TX_FC_RESPONSE_FREQ) - {} + { + } }; /*********************************************************************** * I/O Interface **********************************************************************/ - uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &); - uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &); - bool recv_async_msg(uhd::async_metadata_t &async_metadata, double timeout); + uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t&); + uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t&); + bool recv_async_msg(uhd::async_metadata_t& async_metadata, double timeout); /*********************************************************************** * Other public APIs **********************************************************************/ - rfnoc::graph::sptr create_graph(const std::string &name=""); + rfnoc::graph::sptr create_graph(const std::string& name = ""); protected: /*********************************************************************** @@ -172,10 +172,10 @@ protected: **********************************************************************/ // The 'rate' argument is so we can use these as subscribers to rate changes public: // TODO make these protected again - void update_rx_streamers(double rate=-1.0); - void update_tx_streamers(double rate=-1.0); -protected: + void update_rx_streamers(double rate = -1.0); + void update_tx_streamers(double rate = -1.0); +protected: /*********************************************************************** * Transport-related **********************************************************************/ @@ -187,17 +187,21 @@ protected: * The source address in this value is not considered, only the * destination address. * \param xport_type Specify which kind of transport this is. - * \param args Additional arguments for the transport generation. See \ref page_transport - * for valid arguments. + * \param args Additional arguments for the transport generation. See \ref + * page_transport for valid arguments. */ - virtual uhd::both_xports_t make_transport( - const uhd::sid_t &address, + virtual uhd::both_xports_t make_transport(const uhd::sid_t& address, const xport_type_t xport_type, - const uhd::device_addr_t& args - ) = 0; + const uhd::device_addr_t& args) = 0; - virtual uhd::device_addr_t get_tx_hints(size_t) { return uhd::device_addr_t(); } - virtual uhd::device_addr_t get_rx_hints(size_t) { return uhd::device_addr_t(); } + virtual uhd::device_addr_t get_tx_hints(size_t) + { + return uhd::device_addr_t(); + } + virtual uhd::device_addr_t get_rx_hints(size_t) + { + return uhd::device_addr_t(); + } //! Is called after a streamer is generated virtual void post_streamer_hooks(uhd::direction_t) {} @@ -216,29 +220,25 @@ protected: * \param chan_args New channel args. Must have same length as chan_ids. * */ - void merge_channel_defs( - const std::vector<rfnoc::block_id_t> &chan_ids, - const std::vector<uhd::device_addr_t> &chan_args, - const uhd::direction_t dir - ); + void merge_channel_defs(const std::vector<rfnoc::block_id_t>& chan_ids, + const std::vector<uhd::device_addr_t>& chan_args, + const uhd::direction_t dir); /*********************************************************************** * RFNoC-Specific **********************************************************************/ - void enumerate_rfnoc_blocks( - size_t device_index, - size_t n_blocks, - size_t base_port, - const uhd::sid_t &base_sid, - uhd::device_addr_t transport_args - ); + void enumerate_rfnoc_blocks(size_t device_index, + size_t n_blocks, + size_t base_port, + const uhd::sid_t& base_sid, + uhd::device_addr_t transport_args); /*********************************************************************** * Members **********************************************************************/ // TODO: Maybe move these to private - uhd::dict<std::string, boost::weak_ptr<uhd::rx_streamer> > _rx_streamers; - uhd::dict<std::string, boost::weak_ptr<uhd::tx_streamer> > _tx_streamers; + uhd::dict<std::string, boost::weak_ptr<uhd::rx_streamer>> _rx_streamers; + uhd::dict<std::string, boost::weak_ptr<uhd::tx_streamer>> _tx_streamers; private: /*********************************************************************** diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp index 7afa2ace0..c0f91368d 100644 --- a/host/lib/usrp/device3/device3_io_impl.cpp +++ b/host/lib/usrp/device3/device3_io_impl.cpp @@ -7,16 +7,16 @@ // Provides streaming-related functions which are used by device3 objects. -#include "device3_impl.hpp" #include "device3_flow_ctrl.hpp" +#include "device3_impl.hpp" #include <uhd/rfnoc/constants.hpp> -#include <uhd/rfnoc/source_block_ctrl_base.hpp> +#include <uhd/rfnoc/radio_ctrl.hpp> +#include <uhd/rfnoc/rate_node_ctrl.hpp> #include <uhd/rfnoc/sink_block_ctrl_base.hpp> +#include <uhd/rfnoc/source_block_ctrl_base.hpp> +#include <uhd/transport/zero_copy_flow_ctrl.hpp> #include <uhd/utils/byteswap.hpp> #include <uhd/utils/log.hpp> -#include <uhd/rfnoc/rate_node_ctrl.hpp> -#include <uhd/rfnoc/radio_ctrl.hpp> -#include <uhd/transport/zero_copy_flow_ctrl.hpp> #include <uhdlib/rfnoc/rx_stream_terminator.hpp> #include <uhdlib/rfnoc/tx_stream_terminator.hpp> #include <uhdlib/usrp/common/async_packet_handler.hpp> @@ -32,7 +32,7 @@ using namespace uhd::transport; /*********************************************************************** * Helper functions for get_?x_stream() **********************************************************************/ -static uhd::stream_args_t sanitize_stream_args(const uhd::stream_args_t &args_) +static uhd::stream_args_t sanitize_stream_args(const uhd::stream_args_t& args_) { uhd::stream_args_t args = args_; if (args.channels.empty()) { @@ -42,31 +42,33 @@ static uhd::stream_args_t sanitize_stream_args(const uhd::stream_args_t &args_) return args; } -static void check_stream_sig_compatible(const rfnoc::stream_sig_t &stream_sig, stream_args_t &args, const std::string &tx_rx) +static void check_stream_sig_compatible( + const rfnoc::stream_sig_t& stream_sig, stream_args_t& args, const std::string& tx_rx) { if (args.otw_format.empty()) { if (stream_sig.item_type.empty()) { - throw uhd::runtime_error(str( - boost::format("[%s Streamer] No otw_format defined!") % tx_rx - )); + throw uhd::runtime_error( + str(boost::format("[%s Streamer] No otw_format defined!") % tx_rx)); } else { args.otw_format = stream_sig.item_type; } - } else if (not stream_sig.item_type.empty() and stream_sig.item_type != args.otw_format) { - throw uhd::runtime_error(str( - boost::format("[%s Streamer] Conflicting OTW types defined: args.otw_format = '%s' <=> stream_sig.item_type = '%s'") - % tx_rx % args.otw_format % stream_sig.item_type - )); + } else if (not stream_sig.item_type.empty() + and stream_sig.item_type != args.otw_format) { + throw uhd::runtime_error( + str(boost::format("[%s Streamer] Conflicting OTW types defined: " + "args.otw_format = '%s' <=> stream_sig.item_type = '%s'") + % tx_rx % args.otw_format % stream_sig.item_type)); } const size_t bpi = convert::get_bytes_per_item(args.otw_format); // bytes per item if (stream_sig.packet_size) { if (args.args.has_key("spp")) { size_t args_spp = args.args.cast<size_t>("spp", 0); if (args_spp * bpi != stream_sig.packet_size) { - throw uhd::runtime_error(str( - boost::format("[%s Streamer] Conflicting packet sizes defined: args yields %d bytes but stream_sig.packet_size is %d bytes") - % tx_rx % (args_spp * bpi) % stream_sig.packet_size - )); + throw uhd::runtime_error( + str(boost::format( + "[%s Streamer] Conflicting packet sizes defined: args yields " + "%d bytes but stream_sig.packet_size is %d bytes") + % tx_rx % (args_spp * bpi) % stream_sig.packet_size)); } } else { args.args["spp"] = str(boost::format("%d") % (stream_sig.packet_size / bpi)); @@ -82,19 +84,18 @@ static void check_stream_sig_compatible(const rfnoc::stream_sig_t &stream_sig, s * * \param args_ Stream args. * \param[out] chan_list The list of channels in the correct order. - * \param[out] chan_args Channel args for every channel. `chan_args.size() == chan_list.size()` + * \param[out] chan_args Channel args for every channel. `chan_args.size() == + * chan_list.size()` */ -void generate_channel_list( - const uhd::stream_args_t &args_, - std::vector<uhd::rfnoc::block_id_t> &chan_list, - std::vector<device_addr_t> &chan_args -) { +void generate_channel_list(const uhd::stream_args_t& args_, + std::vector<uhd::rfnoc::block_id_t>& chan_list, + std::vector<device_addr_t>& chan_args) +{ uhd::stream_args_t args = args_; std::vector<uhd::rfnoc::block_id_t> chan_list_(args.channels.size()); std::vector<device_addr_t> chan_args_(args.channels.size()); - for (size_t i = 0; i < args.channels.size(); i++) - { + for (size_t i = 0; i < args.channels.size(); i++) { // Extract block ID size_t chan_idx = args.channels[i]; std::string key = str(boost::format("block_id%d") % chan_idx); @@ -103,10 +104,10 @@ void generate_channel_list( } else if (args.args.has_key("block_id")) { chan_list_[i] = args.args["block_id"]; } else { - throw uhd::runtime_error(str( - boost::format("Cannot create streamers: No block_id specified for channel %d.") - % chan_idx - )); + throw uhd::runtime_error( + str(boost::format( + "Cannot create streamers: No block_id specified for channel %d.") + % chan_idx)); } // Split off known channel specific args @@ -125,7 +126,7 @@ void generate_channel_list( } // Add all remaining args to all channel args - for(device_addr_t &chan_arg: chan_args_) { + for (device_addr_t& chan_arg : chan_args_) { chan_arg = chan_arg.to_string() + "," + args.args.to_string(); } @@ -154,25 +155,20 @@ void generate_channel_list( * \returns The size of the flow control window in number of packets */ static size_t get_rx_flow_control_window( - size_t pkt_size, - size_t sw_buff_size, - const device_addr_t& rx_args -) { + size_t pkt_size, size_t sw_buff_size, const device_addr_t& rx_args) +{ double fullness_factor = rx_args.cast<double>( - "recv_buff_fullness", - uhd::rfnoc::DEFAULT_FC_RX_SW_BUFF_FULL_FACTOR - ); + "recv_buff_fullness", uhd::rfnoc::DEFAULT_FC_RX_SW_BUFF_FULL_FACTOR); if (fullness_factor < 0.01 || fullness_factor > 1) { - throw uhd::value_error("recv_buff_fullness must be in [0.01, 1] inclusive (1% to 100%)"); + throw uhd::value_error( + "recv_buff_fullness must be in [0.01, 1] inclusive (1% to 100%)"); } size_t window_in_bytes = (static_cast<size_t>(sw_buff_size * fullness_factor)); if (rx_args.has_key("max_recv_window")) { window_in_bytes = std::min( - window_in_bytes, - rx_args.cast<size_t>("max_recv_window", window_in_bytes) - ); + window_in_bytes, rx_args.cast<size_t>("max_recv_window", window_in_bytes)); } if (window_in_bytes < pkt_size) { throw uhd::value_error("recv_buff_size must be larger than the recv_frame_size."); @@ -200,32 +196,28 @@ struct async_tx_info_t * * This is run inside a uhd::task as long as this streamer lives. */ -static void handle_tx_async_msgs( - boost::shared_ptr<async_tx_info_t> async_info, - zero_copy_if::sptr xport, - uint32_t (*to_host)(uint32_t), - void (*unpack)(const uint32_t *packet_buff, vrt::if_packet_info_t &), - boost::function<double(void)> get_tick_rate -) { +static void handle_tx_async_msgs(boost::shared_ptr<async_tx_info_t> async_info, + zero_copy_if::sptr xport, + uint32_t (*to_host)(uint32_t), + void (*unpack)(const uint32_t* packet_buff, vrt::if_packet_info_t&), + boost::function<double(void)> get_tick_rate) +{ managed_recv_buffer::sptr buff = xport->get_recv_buff(); - if (not buff) - { + if (not buff) { return; } - //extract packet info + // extract packet info vrt::if_packet_info_t if_packet_info; - if_packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); - const uint32_t *packet_buff = buff->cast<const uint32_t *>(); + if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); + const uint32_t* packet_buff = buff->cast<const uint32_t*>(); - //unpacking can fail - try - { + // unpacking can fail + try { unpack(packet_buff, if_packet_info); - } - catch(const std::exception &ex) - { - UHD_LOGGER_ERROR("STREAMER") << "Error parsing async message packet: " << ex.what() ; + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("STREAMER") + << "Error parsing async message packet: " << ex.what(); return; } @@ -234,21 +226,20 @@ static void handle_tx_async_msgs( tick_rate = 1; } - //fill in the async metadata + // fill in the async metadata async_metadata_t metadata; - load_metadata_from_buff( - to_host, - metadata, - if_packet_info, - packet_buff, - tick_rate, - async_info->stream_channel - ); + load_metadata_from_buff(to_host, + metadata, + if_packet_info, + packet_buff, + tick_rate, + async_info->stream_channel); // Filter out any flow control messages and cache the rest - if (metadata.event_code == DEVICE3_ASYNC_EVENT_CODE_FLOW_CTRL) - { - UHD_LOGGER_ERROR("TX ASYNC MSG") << "Unexpected flow control message found in async message handling" << std::endl; + if (metadata.event_code == DEVICE3_ASYNC_EVENT_CODE_FLOW_CTRL) { + UHD_LOGGER_ERROR("TX ASYNC MSG") + << "Unexpected flow control message found in async message handling" + << std::endl; } else { async_info->async_queue->push_with_pop_on_full(metadata); metadata.channel = async_info->device_channel; @@ -257,9 +248,7 @@ static void handle_tx_async_msgs( } } -bool device3_impl::recv_async_msg( - async_metadata_t &async_metadata, double timeout -) +bool device3_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout) { return _async_md->pop_with_timed_wait(async_metadata, timeout); } @@ -269,10 +258,11 @@ bool device3_impl::recv_async_msg( **********************************************************************/ void device3_impl::update_rx_streamers(double /* rate */) { - for(const std::string &block_id: _rx_streamers.keys()) { + for (const std::string& block_id : _rx_streamers.keys()) { UHD_RX_STREAMER_LOG() << "updating RX streamer to " << block_id; boost::shared_ptr<device3_recv_packet_streamer> my_streamer = - boost::dynamic_pointer_cast<device3_recv_packet_streamer>(_rx_streamers[block_id].lock()); + boost::dynamic_pointer_cast<device3_recv_packet_streamer>( + _rx_streamers[block_id].lock()); if (my_streamer) { double tick_rate = my_streamer->get_terminator()->get_tick_rate(); if (tick_rate == rfnoc::tick_node_ctrl::RATE_UNDEFINED) { @@ -285,9 +275,11 @@ void device3_impl::update_rx_streamers(double /* rate */) } double scaling = my_streamer->get_terminator()->get_output_scale_factor(); if (scaling == rfnoc::scalar_node_ctrl::SCALE_UNDEFINED) { - scaling = 1/32767.; + scaling = 1 / 32767.; } - UHD_RX_STREAMER_LOG() << " New tick_rate == " << tick_rate << " New samp_rate == " << samp_rate << " New scaling == " << scaling ; + UHD_RX_STREAMER_LOG() + << " New tick_rate == " << tick_rate + << " New samp_rate == " << samp_rate << " New scaling == " << scaling; my_streamer->set_tick_rate(tick_rate); my_streamer->set_samp_rate(samp_rate); @@ -296,7 +288,7 @@ void device3_impl::update_rx_streamers(double /* rate */) } } -rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t &args_) +rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t& args_) { boost::mutex::scoped_lock lock(_transport_setup_mutex); stream_args_t args = sanitize_stream_args(args_); @@ -312,88 +304,83 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t &args_) // The terminator's lifetime is coupled to the streamer. // There is only one terminator. If the streamer has multiple channels, // it will be connected to each upstream block. - rfnoc::rx_stream_terminator::sptr recv_terminator = rfnoc::rx_stream_terminator::make(); - for (size_t stream_i = 0; stream_i < chan_list.size(); stream_i++) - { + rfnoc::rx_stream_terminator::sptr recv_terminator = + rfnoc::rx_stream_terminator::make(); + for (size_t stream_i = 0; stream_i < chan_list.size(); stream_i++) { // First, configure blocks and create transport // Get block ID and mb index uhd::rfnoc::block_id_t block_id = chan_list[stream_i]; - UHD_RX_STREAMER_LOG() << "chan " << stream_i << " connecting to " << block_id ; + UHD_RX_STREAMER_LOG() << "chan " << stream_i << " connecting to " << block_id; // Update args so args.args is always valid for this particular channel: - args.args = chan_args[stream_i]; + args.args = chan_args[stream_i]; size_t mb_index = block_id.get_device_no(); - size_t suggested_block_port = args.args.cast<size_t>("block_port", rfnoc::ANY_PORT); + size_t suggested_block_port = + args.args.cast<size_t>("block_port", rfnoc::ANY_PORT); // Access to this channel's block control uhd::rfnoc::source_block_ctrl_base::sptr blk_ctrl = - boost::dynamic_pointer_cast<uhd::rfnoc::source_block_ctrl_base>(get_block_ctrl(block_id)); + boost::dynamic_pointer_cast<uhd::rfnoc::source_block_ctrl_base>( + get_block_ctrl(block_id)); // Connect the terminator with this channel's block. size_t block_port = blk_ctrl->connect_downstream( - recv_terminator, - suggested_block_port, - args.args - ); + recv_terminator, suggested_block_port, args.args); const size_t terminator_port = recv_terminator->connect_upstream(blk_ctrl); blk_ctrl->set_downstream_port(block_port, terminator_port); recv_terminator->set_upstream_port(terminator_port, block_port); // Check if the block connection is compatible (spp and item type) - check_stream_sig_compatible(blk_ctrl->get_output_signature(block_port), args, "RX"); + check_stream_sig_compatible( + blk_ctrl->get_output_signature(block_port), args, "RX"); // Setup the DSP transport hints device_addr_t rx_hints = get_rx_hints(mb_index); - //allocate sid and create transport + // allocate sid and create transport uhd::sid_t stream_address = blk_ctrl->get_address(block_port); - UHD_RX_STREAMER_LOG() << "creating rx stream " << rx_hints.to_string() ; + UHD_RX_STREAMER_LOG() << "creating rx stream " << rx_hints.to_string(); both_xports_t xport = make_transport(stream_address, RX_DATA, rx_hints); - UHD_RX_STREAMER_LOG() << std::hex << "data_sid = " << xport.send_sid << std::dec << " actual recv_buff_size = " << xport.recv_buff_size; + UHD_RX_STREAMER_LOG() << std::hex << "data_sid = " << xport.send_sid << std::dec + << " actual recv_buff_size = " << xport.recv_buff_size; // Configure the block // Flow control setup const size_t pkt_size = xport.recv->get_recv_frame_size(); // Leave one pkt_size space for overrun packets - TODO make this obsolete - const size_t fc_window = get_rx_flow_control_window(pkt_size, xport.recv_buff_size, rx_hints) - pkt_size; - const size_t fc_handle_window = std::max<size_t>(1, fc_window / stream_options.rx_fc_request_freq); - UHD_RX_STREAMER_LOG()<< "Flow Control Window = " << (fc_window) << ", Flow Control Handler Window = " << fc_handle_window; - blk_ctrl->configure_flow_control_out( - true, + const size_t fc_window = + get_rx_flow_control_window(pkt_size, xport.recv_buff_size, rx_hints) + - pkt_size; + const size_t fc_handle_window = + std::max<size_t>(1, fc_window / stream_options.rx_fc_request_freq); + UHD_RX_STREAMER_LOG() << "Flow Control Window = " << (fc_window) + << ", Flow Control Handler Window = " << fc_handle_window; + blk_ctrl->configure_flow_control_out(true, fc_window, - rx_hints.cast<size_t>("recv_pkt_limit", 0), // On rfnoc-devel, update e300_impl::get_rx_hints() to set this to 32 - block_port - ); + rx_hints.cast<size_t>("recv_pkt_limit", + 0), // On rfnoc-devel, update e300_impl::get_rx_hints() to set this to 32 + block_port); // Add flow control transport boost::shared_ptr<rx_fc_cache_t> fc_cache(new rx_fc_cache_t()); - fc_cache->sid = xport.send_sid; - fc_cache->xport = xport.send; + fc_cache->sid = xport.send_sid; + fc_cache->xport = xport.send; fc_cache->interval = fc_handle_window; - if (xport.endianness == ENDIANNESS_BIG) - { - fc_cache->to_host = uhd::ntohx<uint32_t>; + if (xport.endianness == ENDIANNESS_BIG) { + fc_cache->to_host = uhd::ntohx<uint32_t>; fc_cache->from_host = uhd::htonx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_be; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; - } - else - { - fc_cache->to_host = uhd::wtohx<uint32_t>; + fc_cache->pack = vrt::chdr::if_hdr_pack_be; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; + } else { + fc_cache->to_host = uhd::wtohx<uint32_t>; fc_cache->from_host = uhd::htowx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_le; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_le; + fc_cache->pack = vrt::chdr::if_hdr_pack_le; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_le; } - xport.recv = zero_copy_flow_ctrl::make - ( - xport.recv, - NULL, - [fc_cache](managed_buffer::sptr buff) { - return rx_flow_ctrl( - fc_cache, - buff); - } - ); + xport.recv = zero_copy_flow_ctrl::make( + xport.recv, NULL, [fc_cache](managed_buffer::sptr buff) { + return rx_flow_ctrl(fc_cache, buff); + }); // Configure the block // Note: We need to set_destination() after writing to SR_CLEAR_TX_FC. @@ -406,36 +393,41 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t &args_) blk_ctrl->set_destination(xport.send_sid.get_src(), block_port); // Configure routing for responses - blk_ctrl->sr_write(uhd::rfnoc::SR_RESP_OUT_DST_SID, xport.send_sid.get_src(), block_port); - UHD_RX_STREAMER_LOG() << "resp_out_dst_sid == " << xport.send_sid.get_src() ; + blk_ctrl->sr_write( + uhd::rfnoc::SR_RESP_OUT_DST_SID, xport.send_sid.get_src(), block_port); + UHD_RX_STREAMER_LOG() << "resp_out_dst_sid == " << xport.send_sid.get_src(); // Find all upstream radio nodes and set their response in SID to the host - std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl> > upstream_radio_nodes = blk_ctrl->find_upstream_node<uhd::rfnoc::radio_ctrl>(); - UHD_RX_STREAMER_LOG() << "Number of upstream radio nodes: " << upstream_radio_nodes.size(); - for(const boost::shared_ptr<uhd::rfnoc::radio_ctrl> &node: upstream_radio_nodes) { - node->sr_write(uhd::rfnoc::SR_RESP_OUT_DST_SID, xport.send_sid.get_src(), block_port); + std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl>> upstream_radio_nodes = + blk_ctrl->find_upstream_node<uhd::rfnoc::radio_ctrl>(); + UHD_RX_STREAMER_LOG() << "Number of upstream radio nodes: " + << upstream_radio_nodes.size(); + for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl>& node : + upstream_radio_nodes) { + node->sr_write( + uhd::rfnoc::SR_RESP_OUT_DST_SID, xport.send_sid.get_src(), block_port); } // Second, configure the streamer - //make the new streamer given the samples per packet - if (not my_streamer) - { - // To calculate the max number of samples per packet, we assume the maximum header length - // to avoid fragmentation should the entire header be used. - const size_t bpp = pkt_size - stream_options.rx_max_len_hdr; // bytes per packet - const size_t bpi = convert::get_bytes_per_item(args.otw_format); // bytes per item - const size_t spp = std::min(args.args.cast<size_t>("spp", bpp/bpi), bpp/bpi); // samples per packet - UHD_RX_STREAMER_LOG() << "spp == " << spp ; + // make the new streamer given the samples per packet + if (not my_streamer) { + // To calculate the max number of samples per packet, we assume the maximum + // header length to avoid fragmentation should the entire header be used. + const size_t bpp = + pkt_size - stream_options.rx_max_len_hdr; // bytes per packet + const size_t bpi = + convert::get_bytes_per_item(args.otw_format); // bytes per item + const size_t spp = std::min(args.args.cast<size_t>("spp", bpp / bpi), + bpp / bpi); // samples per packet + UHD_RX_STREAMER_LOG() << "spp == " << spp; my_streamer = boost::make_shared<device3_recv_packet_streamer>( - spp, - recv_terminator, - xport); + spp, recv_terminator, xport); my_streamer->resize(chan_list.size()); } - //init some streamer stuff + // init some streamer stuff std::string conv_endianness; if (xport.endianness == ENDIANNESS_BIG) { my_streamer->set_vrt_unpacker(&vrt::chdr::if_hdr_unpack_be); @@ -445,63 +437,51 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t &args_) conv_endianness = "le"; } - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.otw_format + "_item32_" + conv_endianness; - id.num_inputs = 1; + id.input_format = args.otw_format + "_item32_" + conv_endianness; + id.num_inputs = 1; id.output_format = args.cpu_format; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); // Give the streamer a functor to handle flow control ACK messages my_streamer->set_xport_handle_flowctrl_ack( - stream_i, - [fc_cache](const uint32_t *payload) { - handle_rx_flowctrl_ack( - fc_cache, - payload - ); - } - ); + stream_i, [fc_cache](const uint32_t* payload) { + handle_rx_flowctrl_ack(fc_cache, payload); + }); - //Give the streamer a functor to get the recv_buffer - my_streamer->set_xport_chan_get_buff( - stream_i, - [xport](double timeout) { - return xport.recv->get_recv_buff(timeout); - }, + // Give the streamer a functor to get the recv_buffer + my_streamer->set_xport_chan_get_buff(stream_i, + [xport](double timeout) { return xport.recv->get_recv_buff(timeout); }, true /*flush*/ ); - //Give the streamer a functor to handle overruns - //bind requires a weak_ptr to break the a streamer->streamer circular dependency - //Using "this" is OK because we know that this device3_impl will outlive the streamer + // Give the streamer a functor to handle overruns + // bind requires a weak_ptr to break the a streamer->streamer circular dependency + // Using "this" is OK because we know that this device3_impl will outlive the + // streamer boost::weak_ptr<uhd::rx_streamer> weak_ptr(my_streamer); my_streamer->set_overflow_handler( - stream_i, - [recv_terminator, weak_ptr, stream_i]() { - recv_terminator->handle_overrun( - weak_ptr, - stream_i); - } - ); + stream_i, [recv_terminator, weak_ptr, stream_i]() { + recv_terminator->handle_overrun(weak_ptr, stream_i); + }); - //Give the streamer a functor issue stream cmd + // Give the streamer a functor issue stream cmd my_streamer->set_issue_stream_cmd( - stream_i, - [blk_ctrl, block_port](const stream_cmd_t& stream_cmd) { + stream_i, [blk_ctrl, block_port](const stream_cmd_t& stream_cmd) { blk_ctrl->issue_stream_cmd(stream_cmd, block_port); - } - ); + }); } // Notify all blocks in this chain that they are connected to an active streamer recv_terminator->set_rx_streamer(true, 0); - // Store a weak pointer to prevent a streamer->device3_impl->streamer circular dependency. - // Note that we store the streamer only once, and use its terminator's - // ID to do so. - _rx_streamers[recv_terminator->unique_id()] = boost::weak_ptr<uhd::rx_streamer>(my_streamer); + // Store a weak pointer to prevent a streamer->device3_impl->streamer circular + // dependency. Note that we store the streamer only once, and use its terminator's ID + // to do so. + _rx_streamers[recv_terminator->unique_id()] = + boost::weak_ptr<uhd::rx_streamer>(my_streamer); // Sets tick rate, samp rate and scaling on this streamer. // A registered terminator is required to do this. @@ -516,10 +496,11 @@ rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t &args_) **********************************************************************/ void device3_impl::update_tx_streamers(double /* rate */) { - for(const std::string &block_id: _tx_streamers.keys()) { + for (const std::string& block_id : _tx_streamers.keys()) { UHD_TX_STREAMER_LOG() << "updating TX streamer: " << block_id; boost::shared_ptr<device3_send_packet_streamer> my_streamer = - boost::dynamic_pointer_cast<device3_send_packet_streamer>(_tx_streamers[block_id].lock()); + boost::dynamic_pointer_cast<device3_send_packet_streamer>( + _tx_streamers[block_id].lock()); if (my_streamer) { double tick_rate = my_streamer->get_terminator()->get_tick_rate(); if (tick_rate == rfnoc::tick_node_ctrl::RATE_UNDEFINED) { @@ -533,7 +514,9 @@ void device3_impl::update_tx_streamers(double /* rate */) if (scaling == rfnoc::scalar_node_ctrl::SCALE_UNDEFINED) { scaling = 32767.; } - UHD_TX_STREAMER_LOG() << "New tick_rate == " << tick_rate << " New samp_rate == " << samp_rate << " New scaling == " << scaling ; + UHD_TX_STREAMER_LOG() + << "New tick_rate == " << tick_rate << " New samp_rate == " << samp_rate + << " New scaling == " << scaling; my_streamer->set_tick_rate(tick_rate); my_streamer->set_samp_rate(samp_rate); my_streamer->set_scale_factor(scaling); @@ -541,7 +524,7 @@ void device3_impl::update_tx_streamers(double /* rate */) } } -tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) +tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t& args_) { boost::mutex::scoped_lock lock(_transport_setup_mutex); stream_args_t args = sanitize_stream_args(args_); @@ -552,108 +535,111 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) generate_channel_list(args, chan_list, chan_args); // Note: All 'args.args' are merged into chan_args now. - //shared async queue for all channels in streamer - boost::shared_ptr<async_md_type> async_md(new async_md_type(1000/*messages deep*/)); + // shared async queue for all channels in streamer + boost::shared_ptr<async_md_type> async_md(new async_md_type(1000 /*messages deep*/)); // II. Iterate over all channels boost::shared_ptr<device3_send_packet_streamer> my_streamer; // The terminator's lifetime is coupled to the streamer. // There is only one terminator. If the streamer has multiple channels, // it will be connected to each downstream block. - rfnoc::tx_stream_terminator::sptr send_terminator = rfnoc::tx_stream_terminator::make(); - for (size_t stream_i = 0; stream_i < chan_list.size(); stream_i++) - { + rfnoc::tx_stream_terminator::sptr send_terminator = + rfnoc::tx_stream_terminator::make(); + for (size_t stream_i = 0; stream_i < chan_list.size(); stream_i++) { // First, configure the downstream blocks and create the transports // Get block ID and mb index uhd::rfnoc::block_id_t block_id = chan_list[stream_i]; // Update args so args.args is always valid for this particular channel: - args.args = chan_args[stream_i]; + args.args = chan_args[stream_i]; size_t mb_index = block_id.get_device_no(); - size_t suggested_block_port = args.args.cast<size_t>("block_port", rfnoc::ANY_PORT); + size_t suggested_block_port = + args.args.cast<size_t>("block_port", rfnoc::ANY_PORT); // Access to this channel's block control uhd::rfnoc::sink_block_ctrl_base::sptr blk_ctrl = - boost::dynamic_pointer_cast<uhd::rfnoc::sink_block_ctrl_base>(get_block_ctrl(block_id)); + boost::dynamic_pointer_cast<uhd::rfnoc::sink_block_ctrl_base>( + get_block_ctrl(block_id)); // Connect the terminator with this channel's block. // This will throw if the connection is not possible. - size_t block_port = blk_ctrl->connect_upstream( - send_terminator, - suggested_block_port, - args.args - ); + size_t block_port = + blk_ctrl->connect_upstream(send_terminator, suggested_block_port, args.args); const size_t terminator_port = send_terminator->connect_downstream(blk_ctrl); blk_ctrl->set_upstream_port(block_port, terminator_port); send_terminator->set_downstream_port(terminator_port, block_port); // Check if the block connection is compatible (spp and item type) - check_stream_sig_compatible(blk_ctrl->get_input_signature(block_port), args, "TX"); + check_stream_sig_compatible( + blk_ctrl->get_input_signature(block_port), args, "TX"); // Setup the dsp transport hints device_addr_t tx_hints = get_tx_hints(mb_index); const size_t fifo_size = blk_ctrl->get_fifo_size(block_port); // Allocate sid and create transport uhd::sid_t stream_address = blk_ctrl->get_address(block_port); - UHD_TX_STREAMER_LOG() << "creating tx stream " << tx_hints.to_string() ; + UHD_TX_STREAMER_LOG() << "creating tx stream " << tx_hints.to_string(); both_xports_t xport = make_transport(stream_address, TX_DATA, tx_hints); - both_xports_t async_xport = make_transport(stream_address, ASYNC_MSG, device_addr_t("")); - UHD_TX_STREAMER_LOG() << std::hex << "data_sid = " << xport.send_sid << std::dec ; + both_xports_t async_xport = + make_transport(stream_address, ASYNC_MSG, device_addr_t("")); + UHD_TX_STREAMER_LOG() << std::hex << "data_sid = " << xport.send_sid << std::dec; // Configure flow control // This disables the FC module's output, do this before configuring flow control blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0x1, block_port); blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0x0, block_port); // Configure flow control on downstream block - const size_t fc_window = std::min(tx_hints.cast<size_t>("send_buff_size", fifo_size), fifo_size); - const size_t fc_handle_window = std::max<size_t>(1, fc_window / stream_options.tx_fc_response_freq); - UHD_TX_STREAMER_LOG() << "Flow Control Window = " << fc_window << ", Flow Control Handler Window = " << fc_handle_window ; - blk_ctrl->configure_flow_control_in( - fc_handle_window, /*bytes*/ - block_port - ); + const size_t fc_window = + std::min(tx_hints.cast<size_t>("send_buff_size", fifo_size), fifo_size); + const size_t fc_handle_window = + std::max<size_t>(1, fc_window / stream_options.tx_fc_response_freq); + UHD_TX_STREAMER_LOG() << "Flow Control Window = " << fc_window + << ", Flow Control Handler Window = " << fc_handle_window; + blk_ctrl->configure_flow_control_in(fc_handle_window, /*bytes*/ + block_port); // Add flow control transport boost::shared_ptr<tx_fc_cache_t> fc_cache(new tx_fc_cache_t(fc_window)); - if (xport.endianness == ENDIANNESS_BIG) - { - fc_cache->to_host = uhd::ntohx<uint32_t>; + if (xport.endianness == ENDIANNESS_BIG) { + fc_cache->to_host = uhd::ntohx<uint32_t>; fc_cache->from_host = uhd::htonx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_be; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; + fc_cache->pack = vrt::chdr::if_hdr_pack_be; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; } else { - fc_cache->to_host = uhd::wtohx<uint32_t>; + fc_cache->to_host = uhd::wtohx<uint32_t>; fc_cache->from_host = uhd::htowx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_le; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_le; + fc_cache->pack = vrt::chdr::if_hdr_pack_le; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_le; } - xport.send = zero_copy_flow_ctrl::make( - xport.send, + xport.send = zero_copy_flow_ctrl::make(xport.send, [fc_cache, xport](managed_buffer::sptr buff) { - return tx_flow_ctrl( - fc_cache, - xport.recv, - buff); + return tx_flow_ctrl(fc_cache, xport.recv, buff); }, - NULL - ); + NULL); // Configure return path for async messages - blk_ctrl->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, async_xport.recv_sid.get_dst(), block_port); - UHD_TX_STREAMER_LOG() << "resp_in_dst_sid == " << boost::format("0x%04X") % xport.recv_sid.get_dst() ; + blk_ctrl->sr_write( + uhd::rfnoc::SR_RESP_IN_DST_SID, async_xport.recv_sid.get_dst(), block_port); + UHD_TX_STREAMER_LOG() << "resp_in_dst_sid == " + << boost::format("0x%04X") % xport.recv_sid.get_dst(); // FIXME: Once there is a better way to map the radio block and port // to the channel or another way to receive asynchronous messages that // is not in-band, this should be removed. - if (args.args.has_key("radio_id") and args.args.has_key("radio_port")) - { + if (args.args.has_key("radio_id") and args.args.has_key("radio_port")) { // Find downstream radio node and set the response SID to the host uhd::rfnoc::block_id_t radio_id(args.args["radio_id"]); size_t radio_port = args.args.cast<size_t>("radio_port", 0); - std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl> > downstream_radio_nodes = blk_ctrl->find_downstream_node<uhd::rfnoc::radio_ctrl>(); - UHD_TX_STREAMER_LOG() << "Number of downstream radio nodes: " << downstream_radio_nodes.size(); - for(const boost::shared_ptr<uhd::rfnoc::radio_ctrl> &node: downstream_radio_nodes) { + std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl>> + downstream_radio_nodes = + blk_ctrl->find_downstream_node<uhd::rfnoc::radio_ctrl>(); + UHD_TX_STREAMER_LOG() + << "Number of downstream radio nodes: " << downstream_radio_nodes.size(); + for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl>& node : + downstream_radio_nodes) { if (node->get_block_id() == radio_id) { - node->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, async_xport.recv_sid.get_dst(), radio_port); + node->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, + async_xport.recv_sid.get_dst(), + radio_port); } } } else { @@ -663,34 +649,41 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) // is not the same as the block_port. It should be removed as // soon as possible. // Find all downstream radio nodes and set their response SID to the host - std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl> > downstream_radio_nodes = blk_ctrl->find_downstream_node<uhd::rfnoc::radio_ctrl>(); - UHD_TX_STREAMER_LOG() << "Number of downstream radio nodes: " << downstream_radio_nodes.size(); - for(const boost::shared_ptr<uhd::rfnoc::radio_ctrl> &node: downstream_radio_nodes) { - node->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, async_xport.recv_sid.get_dst(), block_port); + std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl>> + downstream_radio_nodes = + blk_ctrl->find_downstream_node<uhd::rfnoc::radio_ctrl>(); + UHD_TX_STREAMER_LOG() + << "Number of downstream radio nodes: " << downstream_radio_nodes.size(); + for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl>& node : + downstream_radio_nodes) { + node->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, + async_xport.recv_sid.get_dst(), + block_port); } } - // Second, configure the streamer now that the blocks and transports are configured - - //make the new streamer given the samples per packet - if (not my_streamer) - { - // To calculate the max number of samples per packet, we assume the maximum header length - // to avoid fragmentation should the entire header be used. - const size_t bpp = tx_hints.cast<size_t>("bpp", xport.send->get_send_frame_size()) - stream_options.tx_max_len_hdr; - const size_t bpi = convert::get_bytes_per_item(args.otw_format); // bytes per item - const size_t spp = std::min(args.args.cast<size_t>("spp", bpp/bpi), bpp/bpi); // samples per packet - UHD_TX_STREAMER_LOG() << "spp == " << spp ; + // Second, configure the streamer now that the blocks and transports are + // configured + + // make the new streamer given the samples per packet + if (not my_streamer) { + // To calculate the max number of samples per packet, we assume the maximum + // header length to avoid fragmentation should the entire header be used. + const size_t bpp = + tx_hints.cast<size_t>("bpp", xport.send->get_send_frame_size()) + - stream_options.tx_max_len_hdr; + const size_t bpi = + convert::get_bytes_per_item(args.otw_format); // bytes per item + const size_t spp = std::min(args.args.cast<size_t>("spp", bpp / bpi), + bpp / bpi); // samples per packet + UHD_TX_STREAMER_LOG() << "spp == " << spp; my_streamer = boost::make_shared<device3_send_packet_streamer>( - spp, - send_terminator, - xport, - async_xport); + spp, send_terminator, xport, async_xport); my_streamer->resize(chan_list.size()); } - //init some streamer stuff + // init some streamer stuff std::string conv_endianness; if (xport.endianness == ENDIANNESS_BIG) { my_streamer->set_vrt_packer(&vrt::chdr::if_hdr_pack_be); @@ -700,69 +693,57 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) conv_endianness = "le"; } - //set the converter + // set the converter uhd::convert::id_type id; - id.input_format = args.cpu_format; - id.num_inputs = 1; + id.input_format = args.cpu_format; + id.num_inputs = 1; id.output_format = args.otw_format + "_item32_" + conv_endianness; - id.num_outputs = 1; + id.num_outputs = 1; my_streamer->set_converter(id); boost::shared_ptr<async_tx_info_t> async_tx_info(new async_tx_info_t()); - async_tx_info->stream_channel = args.channels[stream_i]; - async_tx_info->device_channel = mb_index; - async_tx_info->async_queue = async_md; + async_tx_info->stream_channel = args.channels[stream_i]; + async_tx_info->device_channel = mb_index; + async_tx_info->async_queue = async_md; async_tx_info->old_async_queue = _async_md; - task::sptr async_task = task::make( - [async_tx_info, async_xport, xport, send_terminator]() { - handle_tx_async_msgs( - async_tx_info, - async_xport.recv, - xport.endianness == ENDIANNESS_BIG ? uhd::ntohx<uint32_t> : uhd::wtohx<uint32_t>, - xport.endianness == ENDIANNESS_BIG ? vrt::chdr::if_hdr_unpack_be : vrt::chdr::if_hdr_unpack_le, - [send_terminator]() {return send_terminator->get_tick_rate();} - ); - } - ); + task::sptr async_task = + task::make([async_tx_info, async_xport, xport, send_terminator]() { + handle_tx_async_msgs(async_tx_info, + async_xport.recv, + xport.endianness == ENDIANNESS_BIG ? uhd::ntohx<uint32_t> + : uhd::wtohx<uint32_t>, + xport.endianness == ENDIANNESS_BIG ? vrt::chdr::if_hdr_unpack_be + : vrt::chdr::if_hdr_unpack_le, + [send_terminator]() { return send_terminator->get_tick_rate(); }); + }); my_streamer->add_async_msg_task(async_task); - //Give the streamer a functor to get the send buffer - my_streamer->set_xport_chan_get_buff( - stream_i, - [xport](const double timeout) { - return xport.send->get_send_buff(timeout); - } - ); - //Give the streamer a functor handled received async messages + // Give the streamer a functor to get the send buffer + my_streamer->set_xport_chan_get_buff(stream_i, + [xport](const double timeout) { return xport.send->get_send_buff(timeout); }); + // Give the streamer a functor handled received async messages my_streamer->set_async_receiver( [async_md](uhd::async_metadata_t& md, const double timeout) { return async_md->pop_with_timed_wait(md, timeout); - } - ); + }); my_streamer->set_xport_chan_sid(stream_i, true, xport.send_sid); // CHDR does not support trailers my_streamer->set_enable_trailer(false); - my_streamer->set_xport_chan_post_send_cb( - stream_i, - [fc_cache, xport]() { - tx_flow_ctrl_ack( - fc_cache, - xport.send, - xport.send_sid - ); - } - ); + my_streamer->set_xport_chan_post_send_cb(stream_i, [fc_cache, xport]() { + tx_flow_ctrl_ack(fc_cache, xport.send, xport.send_sid); + }); } // Notify all blocks in this chain that they are connected to an active streamer send_terminator->set_tx_streamer(true, 0); - // Store a weak pointer to prevent a streamer->device3_impl->streamer circular dependency. - // Note that we store the streamer only once, and use its terminator's - // ID to do so. - _tx_streamers[send_terminator->unique_id()] = boost::weak_ptr<uhd::tx_streamer>(my_streamer); + // Store a weak pointer to prevent a streamer->device3_impl->streamer circular + // dependency. Note that we store the streamer only once, and use its terminator's ID + // to do so. + _tx_streamers[send_terminator->unique_id()] = + boost::weak_ptr<uhd::tx_streamer>(my_streamer); // Sets tick rate, samp rate and scaling on this streamer // A registered terminator is required to do this. @@ -771,5 +752,3 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) post_streamer_hooks(TX_DIRECTION); return my_streamer; } - - diff --git a/host/lib/usrp/mpmd/mpmd_devices.hpp b/host/lib/usrp/mpmd/mpmd_devices.hpp index ab0cc1271..9cc046037 100644 --- a/host/lib/usrp/mpmd/mpmd_devices.hpp +++ b/host/lib/usrp/mpmd/mpmd_devices.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_MPMD_DEVICES_HPP #define INCLUDED_MPMD_DEVICES_HPP -#include <vector> #include <string> +#include <vector> static constexpr char MPM_CATCHALL_DEVICE_TYPE[] = "mpm"; diff --git a/host/lib/usrp/mpmd/mpmd_find.cpp b/host/lib/usrp/mpmd/mpmd_find.cpp index 26230e396..5d2406b30 100644 --- a/host/lib/usrp/mpmd/mpmd_find.cpp +++ b/host/lib/usrp/mpmd/mpmd_find.cpp @@ -6,11 +6,11 @@ // find-related code for MPM devices -#include "mpmd_impl.hpp" #include "mpmd_devices.hpp" -#include <uhd/types/device_addr.hpp> -#include <uhd/transport/udp_simple.hpp> +#include "mpmd_impl.hpp" #include <uhd/transport/if_addrs.hpp> +#include <uhd/transport/udp_simple.hpp> +#include <uhd/types/device_addr.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <future> @@ -19,60 +19,50 @@ using namespace uhd; using namespace uhd::mpmd; namespace { - //! How long we wait for discovery responses (in seconds) - constexpr double MPMD_FIND_TIMEOUT = 0.5; - constexpr char MPMD_CHDR_REACHABILITY_KEY[] = "reachable"; - constexpr char MPMD_CHDR_REACHABILITY_NEGATIVE[] = "No"; - //! The preamble for any response on the discovery port. Can be used to - // verify that the response is actually an MPM device. - constexpr char MPM_DISC_RESPONSE_PREAMBLE[] = "USRP-MPM"; - - device_addr_t flag_dev_as_unreachable(const device_addr_t& device_args) - { - device_addr_t flagged_device_args(device_args); - flagged_device_args[MPMD_CHDR_REACHABILITY_KEY] = - MPMD_CHDR_REACHABILITY_NEGATIVE; - return flagged_device_args; - } +//! How long we wait for discovery responses (in seconds) +constexpr double MPMD_FIND_TIMEOUT = 0.5; +constexpr char MPMD_CHDR_REACHABILITY_KEY[] = "reachable"; +constexpr char MPMD_CHDR_REACHABILITY_NEGATIVE[] = "No"; +//! The preamble for any response on the discovery port. Can be used to +// verify that the response is actually an MPM device. +constexpr char MPM_DISC_RESPONSE_PREAMBLE[] = "USRP-MPM"; + +device_addr_t flag_dev_as_unreachable(const device_addr_t& device_args) +{ + device_addr_t flagged_device_args(device_args); + flagged_device_args[MPMD_CHDR_REACHABILITY_KEY] = MPMD_CHDR_REACHABILITY_NEGATIVE; + return flagged_device_args; } +} // namespace device_addrs_t mpmd_find_with_addr( - const std::string& mgmt_addr, - const device_addr_t& hint_ -) { + const std::string& mgmt_addr, const device_addr_t& hint_) +{ UHD_ASSERT_THROW(not mgmt_addr.empty()); const std::string mpm_discovery_port = hint_.get( - mpmd_impl::MPM_DISCOVERY_PORT_KEY, - std::to_string(mpmd_impl::MPM_DISCOVERY_PORT) - ); - UHD_LOG_DEBUG("MPMD", - "Discovering MPM devices on port " << mpm_discovery_port); + mpmd_impl::MPM_DISCOVERY_PORT_KEY, std::to_string(mpmd_impl::MPM_DISCOVERY_PORT)); + UHD_LOG_DEBUG("MPMD", "Discovering MPM devices on port " << mpm_discovery_port); device_addrs_t addrs; - transport::udp_simple::sptr comm = transport::udp_simple::make_broadcast( - mgmt_addr, mpm_discovery_port); - comm->send( - boost::asio::buffer( - mpmd_impl::MPM_DISCOVERY_CMD.c_str(), - mpmd_impl::MPM_DISCOVERY_CMD.size() - ) - ); + transport::udp_simple::sptr comm = + transport::udp_simple::make_broadcast(mgmt_addr, mpm_discovery_port); + comm->send(boost::asio::buffer( + mpmd_impl::MPM_DISCOVERY_CMD.c_str(), mpmd_impl::MPM_DISCOVERY_CMD.size())); while (true) { const size_t MAX_MTU = 8000; - char buff[MAX_MTU] = {}; - const size_t nbytes = comm->recv( - boost::asio::buffer(buff, MAX_MTU), - MPMD_FIND_TIMEOUT - ); + char buff[MAX_MTU] = {}; + const size_t nbytes = + comm->recv(boost::asio::buffer(buff, MAX_MTU), MPMD_FIND_TIMEOUT); if (nbytes == 0) { break; } - const char* reply = (const char*)buff; + const char* reply = (const char*)buff; std::string reply_string = std::string(reply); std::vector<std::string> result; - boost::algorithm::split(result, reply_string, - [](const char& in) { return in == ';'; }, - boost::token_compress_on); + boost::algorithm::split(result, + reply_string, + [](const char& in) { return in == ';'; }, + boost::token_compress_on); if (result.empty()) { continue; } @@ -86,9 +76,8 @@ device_addrs_t mpmd_find_with_addr( // remove external iface addrs if executed directly on device bool external_iface = false; for (const auto& addr : transport::get_if_addrs()) { - if ((addr.inet == comm->get_recv_addr()) && - recv_addr != - boost::asio::ip::address_v4::loopback().to_string()) { + if ((addr.inet == comm->get_recv_addr()) + && recv_addr != boost::asio::ip::address_v4::loopback().to_string()) { external_iface = true; break; } @@ -100,41 +89,40 @@ device_addrs_t mpmd_find_with_addr( // Create result to return device_addr_t new_addr; new_addr[xport::MGMT_ADDR_KEY] = recv_addr; - new_addr["type"] = "mpmd"; // hwd will overwrite this + new_addr["type"] = "mpmd"; // hwd will overwrite this // remove ident string and put other informations into device_args dict result.erase(result.begin()); // parse key-value pairs in the discovery string and add them to the // device_args for (const auto& el : result) { std::vector<std::string> value; - boost::algorithm::split(value, el, - [](const char& in) { return in == '='; }, - boost::token_compress_on); + boost::algorithm::split(value, + el, + [](const char& in) { return in == '='; }, + boost::token_compress_on); if (value[0] != xport::MGMT_ADDR_KEY) { new_addr[value[0]] = value[1]; } } // filter the discovered device below by matching optional keys - if ( - (not hint_.has_key("name") or hint_["name"] == new_addr["name"]) - and (not hint_.has_key("serial") or hint_["serial"] == new_addr["serial"]) - and (not hint_.has_key("type") or hint_["type"] == new_addr["type"] or hint_["type"] == MPM_CATCHALL_DEVICE_TYPE) - and (not hint_.has_key("product") or hint_["product"] == new_addr["product"]) - ){ - UHD_LOG_TRACE("MPMD FIND", - "Found device that matches hints: " << new_addr.to_string()); + if ((not hint_.has_key("name") or hint_["name"] == new_addr["name"]) + and (not hint_.has_key("serial") or hint_["serial"] == new_addr["serial"]) + and (not hint_.has_key("type") or hint_["type"] == new_addr["type"] + or hint_["type"] == MPM_CATCHALL_DEVICE_TYPE) + and (not hint_.has_key("product") + or hint_["product"] == new_addr["product"])) { + UHD_LOG_TRACE( + "MPMD FIND", "Found device that matches hints: " << new_addr.to_string()); addrs.push_back(new_addr); } else { - UHD_LOG_DEBUG("MPMD FIND", - "Found device, but does not match hint: " << recv_addr - ); + UHD_LOG_DEBUG( + "MPMD FIND", "Found device, but does not match hint: " << recv_addr); } } return addrs; }; - // Implements scenario 1) (see below) device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) { @@ -142,10 +130,9 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) device_addrs_t found_devices; found_devices.reserve(hints.size()); for (const auto& hint : hints) { - if (not (hint.has_key(xport::FIRST_ADDR_KEY) or - hint.has_key(xport::MGMT_ADDR_KEY))) { - UHD_LOG_DEBUG("MPMD FIND", - "No address given in hint " << hint.to_string()); + if (not(hint.has_key(xport::FIRST_ADDR_KEY) + or hint.has_key(xport::MGMT_ADDR_KEY))) { + UHD_LOG_DEBUG("MPMD FIND", "No address given in hint " << hint.to_string()); continue; } const std::string mgmt_addr = @@ -154,13 +141,12 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) if (reply_addrs.size() > 1) { UHD_LOG_ERROR("MPMD", "Could not resolve device hint \"" << hint.to_string() - << "\" to a unique device."); + << "\" to a unique device."); continue; } else if (reply_addrs.empty()) { continue; } - UHD_LOG_TRACE("MPMD FIND", - "Device responded: " << reply_addrs[0].to_string()); + UHD_LOG_TRACE("MPMD FIND", "Device responded: " << reply_addrs[0].to_string()); found_devices.push_back(reply_addrs[0]); } if (found_devices.size() == 0) { @@ -175,17 +161,14 @@ device_addrs_t mpmd_find_with_addrs(const device_addrs_t& hints) device_addrs_t mpmd_find_with_bcast(const device_addr_t& hint) { device_addrs_t addrs; - UHD_LOG_TRACE("MPMD FIND", - "Broadcasting on all available interfaces to find MPM devices."); + UHD_LOG_TRACE( + "MPMD FIND", "Broadcasting on all available interfaces to find MPM devices."); std::vector<std::future<device_addrs_t>> task_list; for (const auto& if_addr : transport::get_if_addrs()) { task_list.emplace_back(std::async(std::launch::async, - [if_addr, hint](){ - return mpmd_find_with_addr(if_addr.bcast, hint); - } - )); + [if_addr, hint]() { return mpmd_find_with_addr(if_addr.bcast, hint); })); } - for (auto &task : task_list) { + for (auto& task : task_list) { auto reply_addrs = task.get(); addrs.insert(addrs.begin(), reply_addrs.begin(), reply_addrs.end()); } @@ -212,21 +195,19 @@ device_addrs_t mpmd_find(const device_addr_t& hint_) { device_addrs_t hints = separate_device_addr(hint_); if (hint_.has_key("type")) { - if (std::find(MPM_DEVICE_TYPES.cbegin(), - MPM_DEVICE_TYPES.cend(), - hint_["type"]) == MPM_DEVICE_TYPES.cend()) { - UHD_LOG_TRACE("MPMD FIND", - "Returning early, type does not match an MPM device."); + if (std::find(MPM_DEVICE_TYPES.cbegin(), MPM_DEVICE_TYPES.cend(), hint_["type"]) + == MPM_DEVICE_TYPES.cend()) { + UHD_LOG_TRACE( + "MPMD FIND", "Returning early, type does not match an MPM device."); return {}; } } - UHD_LOG_TRACE("MPMD FIND", - "Finding with " << hints.size() << " different hint(s)."); + UHD_LOG_TRACE("MPMD FIND", "Finding with " << hints.size() << " different hint(s)."); // Scenario 1): User gave us at least one address - if (not hints.empty() and - (hints[0].has_key(xport::FIRST_ADDR_KEY) or - hints[0].has_key(xport::MGMT_ADDR_KEY))) { + if (not hints.empty() + and (hints[0].has_key(xport::FIRST_ADDR_KEY) + or hints[0].has_key(xport::MGMT_ADDR_KEY))) { // Note: We don't try and connect to the devices in this mode, because // we only get here if the user specified addresses, and we assume she // knows what she's doing. @@ -238,33 +219,31 @@ device_addrs_t mpmd_find(const device_addr_t& hint_) hints.resize(1); } const auto bcast_mpm_devs = mpmd_find_with_bcast(hints[0]); - UHD_LOG_TRACE("MPMD FIND", - "Found " << bcast_mpm_devs.size() << " device via broadcast."); + UHD_LOG_TRACE( + "MPMD FIND", "Found " << bcast_mpm_devs.size() << " device via broadcast."); const bool find_all = hint_.has_key(mpmd_impl::MPM_FINDALL_KEY); if (find_all) { UHD_LOG_TRACE("MPMD FIND", - "User provided " << mpmd_impl::MPM_FINDALL_KEY << ", will not " - "check devices for CHDR accessibility."); + "User provided " << mpmd_impl::MPM_FINDALL_KEY + << ", will not " + "check devices for CHDR accessibility."); } // Filter found devices for those that we can actually talk to via CHDR device_addrs_t filtered_mpm_devs; - for (const auto &mpm_dev : bcast_mpm_devs) { - const auto reachable_device_addr = - mpmd_mboard_impl::is_device_reachable(mpm_dev); + for (const auto& mpm_dev : bcast_mpm_devs) { + const auto reachable_device_addr = mpmd_mboard_impl::is_device_reachable(mpm_dev); if (bool(reachable_device_addr)) { filtered_mpm_devs.push_back(reachable_device_addr.get()); } else if (find_all) { - filtered_mpm_devs.emplace_back( - flag_dev_as_unreachable(mpm_dev) - ); + filtered_mpm_devs.emplace_back(flag_dev_as_unreachable(mpm_dev)); } } if (filtered_mpm_devs.empty() and not bcast_mpm_devs.empty()) { UHD_LOG_INFO("MPMD FIND", "Found MPM devices, but none are reachable for a UHD session. " - "Specify " << mpmd_impl::MPM_FINDALL_KEY << " to find all devices." - ); + "Specify " + << mpmd_impl::MPM_FINDALL_KEY << " to find all devices."); } return filtered_mpm_devs; diff --git a/host/lib/usrp/mpmd/mpmd_image_loader.cpp b/host/lib/usrp/mpmd/mpmd_image_loader.cpp index e0b85f897..7553b1df4 100644 --- a/host/lib/usrp/mpmd/mpmd_image_loader.cpp +++ b/host/lib/usrp/mpmd/mpmd_image_loader.cpp @@ -7,66 +7,68 @@ #include "mpmd_impl.hpp" #include <uhd/config.hpp> #include <uhd/device.hpp> -#include <uhd/image_loader.hpp> #include <uhd/exception.hpp> -#include <uhd/types/eeprom.hpp> +#include <uhd/image_loader.hpp> #include <uhd/types/component_file.hpp> +#include <uhd/types/eeprom.hpp> #include <uhd/utils/paths.hpp> #include <boost/algorithm/string.hpp> #include <boost/filesystem/convenience.hpp> -#include <sstream> -#include <string> #include <fstream> #include <iterator> +#include <sstream> #include <streambuf> +#include <string> using namespace uhd; -namespace uhd{ namespace /*anon*/{ - const size_t MD5LEN = 32; // Length of a MD5 hash in chars +namespace uhd { namespace /*anon*/ { +const size_t MD5LEN = 32; // Length of a MD5 hash in chars /* * Helper function to generate a component_file_t using the input ID and path to file. */ uhd::usrp::component_file_t generate_component( - const std::string& id, - const std::string& filepath -) { + const std::string& id, const std::string& filepath) +{ uhd::usrp::component_file_t component_file; // Add an ID to the metadata component_file.metadata["id"] = id; - UHD_LOG_TRACE("MPMD IMAGE LOADER", - "Component ID added to the component dictionary: " << id); + UHD_LOG_TRACE( + "MPMD IMAGE LOADER", "Component ID added to the component dictionary: " << id); // Add the filename to the metadata // Remove the path to the filename - component_file.metadata["filename"] = boost::filesystem::path(filepath).filename().string(); + component_file.metadata["filename"] = + boost::filesystem::path(filepath).filename().string(); UHD_LOG_TRACE("MPMD IMAGE LOADER", - "Component filename added to the component dictionary: " << filepath); + "Component filename added to the component dictionary: " << filepath); // Add the hash, if a hash file exists const std::string component_hash_filepath = filepath + ".md5"; - std::ifstream component_hash_ifstream(component_hash_filepath.c_str(), std::ios::binary); + std::ifstream component_hash_ifstream( + component_hash_filepath.c_str(), std::ios::binary); std::string component_hash; if (component_hash_ifstream.is_open()) { // TODO: Verify that the hash read is valid, ie only contains 0-9a-f. component_hash.resize(MD5LEN); - component_hash_ifstream.read( &component_hash[0], MD5LEN ); + component_hash_ifstream.read(&component_hash[0], MD5LEN); component_hash_ifstream.close(); component_file.metadata["md5"] = component_hash; UHD_LOG_TRACE("MPMD IMAGE LOADER", - "Added component file hash to the component dictionary."); + "Added component file hash to the component dictionary."); } else { // If there is no hash file, don't worry about it too much - UHD_LOG_DEBUG("MPMD IMAGE LOADER", "Could not open component file hash file: " - << component_hash_filepath); + UHD_LOG_DEBUG("MPMD IMAGE LOADER", + "Could not open component file hash file: " << component_hash_filepath); } - // Read the component file image into a structure suitable to sent as a binary string to MPM + // Read the component file image into a structure suitable to sent as a binary string + // to MPM std::vector<uint8_t> data; std::ifstream component_ifstream(filepath.c_str(), std::ios::binary); if (component_ifstream.is_open()) { - data.insert( data.begin(), - std::istreambuf_iterator<char>(component_ifstream), - std::istreambuf_iterator<char>()); + data.insert(data.begin(), + std::istreambuf_iterator<char>(component_ifstream), + std::istreambuf_iterator<char>()); component_ifstream.close(); } else { const std::string err_msg("Component file does not exist: " + filepath); @@ -79,7 +81,8 @@ uhd::usrp::component_file_t generate_component( /* * Function to be registered with uhd_image_loader */ -static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loader_args){ +static bool mpmd_image_loader(const image_loader::image_loader_args_t& image_loader_args) +{ // See if any MPM devices with the given args are found device_addr_t find_hint = image_loader_args.args; find_hint.set("find_all", "1"); // We need to find all devices @@ -94,7 +97,7 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa device_addr_t dev_addr(devs[0]); dev_addr["skip_init"] = "1"; // Make the device - uhd::device::sptr usrp = uhd::device::make(dev_addr, uhd::device::USRP); + uhd::device::sptr usrp = uhd::device::make(dev_addr, uhd::device::USRP); uhd::property_tree::sptr tree = usrp->get_tree(); // Generate the component files @@ -107,44 +110,44 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa if (boost::filesystem::exists(image_loader_args.fpga_path)) { return image_loader_args.fpga_path; } else { - throw uhd::runtime_error(str( - boost::format("FPGA file provided does not exist: %s") - % image_loader_args.fpga_path - )); + throw uhd::runtime_error( + str(boost::format("FPGA file provided does not exist: %s") + % image_loader_args.fpga_path)); } } // Otherwise, we need to generate one else { /* - * The user can specify an FPGA type (HG, XG, AA), rather than a filename. If the user - * does not specify one, this will default to the type currently on the device. If this - * cannot be determined, then the user is forced to specify a filename. - */ + * The user can specify an FPGA type (HG, XG, AA), rather than a filename. If + * the user does not specify one, this will default to the type currently on + * the device. If this cannot be determined, then the user is forced to + * specify a filename. + */ const auto fpga_type = [image_loader_args, tree]() -> std::string { - // If the user didn't provide a type, use the type of currently loaded image on - // the device + // If the user didn't provide a type, use the type of currently loaded + // image on the device if (image_loader_args.args.has_key("fpga")) { return image_loader_args.args.get("fpga"); } else if (tree->exists("/mboards/0/components/fpga")) { - // Pull the FPGA info from the property tree - // The getter should return a vector of a single component_file_t, - // so grab the metadata from that - auto fpga_metadata = - tree->access<uhd::usrp::component_files_t>( - "/mboards/0/components/fpga").get()[0].metadata; - return fpga_metadata.get("type", ""); - // TODO: Do we want to pull the type from the filename if its not - // available in the metadata directly? + // Pull the FPGA info from the property tree + // The getter should return a vector of a single component_file_t, + // so grab the metadata from that + auto fpga_metadata = tree->access<uhd::usrp::component_files_t>( + "/mboards/0/components/fpga") + .get()[0] + .metadata; + return fpga_metadata.get("type", ""); + // TODO: Do we want to pull the type from the filename if its not + // available in the metadata directly? } return ""; }(); // generate_fpga_type lambda function UHD_LOG_TRACE("MPMD IMAGE LOADER", "FPGA type: " << fpga_type); - if(!dev_addr.has_key("product") or fpga_type == ""){ + if (!dev_addr.has_key("product") or fpga_type == "") { throw uhd::runtime_error( - "Found a device but could not auto-generate an image filename."); - } - else { + "Found a device but could not auto-generate an image filename."); + } else { return find_image_path( str(boost::format("usrp_%s_fpga_%s.bit") % (boost::algorithm::to_lower_copy(dev_addr["product"])) @@ -157,9 +160,11 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa all_component_files.push_back(comp_fpga); // DTS component struct // First, we need to determine the name - const std::string base_name = boost::filesystem::change_extension(fpga_path, "").string(); + const std::string base_name = + boost::filesystem::change_extension(fpga_path, "").string(); if (base_name == fpga_path) { - const std::string err_msg("Can't cut extension from FPGA filename... " + fpga_path); + const std::string err_msg( + "Can't cut extension from FPGA filename... " + fpga_path); throw uhd::runtime_error(err_msg); } const std::string dts_path = base_name + ".dts"; @@ -176,20 +181,24 @@ static bool mpmd_image_loader(const image_loader::image_loader_args_t &image_loa // Call RPC to update the component UHD_LOG_INFO("MPMD IMAGE LOADER", "Starting update. This may take a while."); - tree->access<uhd::usrp::component_files_t>("/mboards/0/components/fpga").set(all_component_files); + tree->access<uhd::usrp::component_files_t>("/mboards/0/components/fpga") + .set(all_component_files); UHD_LOG_INFO("MPMD IMAGE LOADER", "Update component function succeeded."); return true; } -}} //namespace uhd::/*anon*/ +}} // namespace uhd:: -UHD_STATIC_BLOCK(register_mpm_image_loader){ +UHD_STATIC_BLOCK(register_mpm_image_loader) +{ // TODO: Update recovery instructions - const std::string recovery_instructions = "Aborting. Your USRP MPM-enabled device's update may or may not have\n" - "completed. The contents of the image files may have been corrupted.\n" - "Please verify those files as soon as possible."; + const std::string recovery_instructions = + "Aborting. Your USRP MPM-enabled device's update may or may not have\n" + "completed. The contents of the image files may have been corrupted.\n" + "Please verify those files as soon as possible."; - //TODO: 'n3xx' doesn't really fit the MPM abstraction, but this is simpler for the time being + // TODO: 'n3xx' doesn't really fit the MPM abstraction, but this is simpler for the + // time being image_loader::register_image_loader("n3xx", mpmd_image_loader, recovery_instructions); image_loader::register_image_loader("e3xx", mpmd_image_loader, recovery_instructions); } diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp index 87e911e17..b8ce6cabd 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_impl.cpp @@ -5,189 +5,166 @@ // #include "mpmd_impl.hpp" -#include <../device3/device3_impl.hpp> #include <uhd/exception.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/tasks.hpp> -#include <uhd/types/sensors.hpp> -#include <uhd/types/eeprom.hpp> #include <uhd/types/component_file.hpp> +#include <uhd/types/eeprom.hpp> +#include <uhd/types/sensors.hpp> #include <uhd/usrp/mboard_eeprom.hpp> -#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> +#include <uhd/utils/static.hpp> +#include <uhd/utils/tasks.hpp> #include <uhdlib/rfnoc/radio_ctrl_impl.hpp> +#include <uhdlib/rfnoc/rpc_block_ctrl.hpp> +#include <../device3/device3_impl.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <boost/make_shared.hpp> #include <boost/thread.hpp> +#include <future> #include <memory> #include <mutex> #include <random> #include <string> -#include <vector> -#include <future> #include <thread> +#include <vector> using namespace uhd; using namespace uhd::mpmd; namespace { - /************************************************************************* - * Local constants - ************************************************************************/ - const size_t MPMD_CROSSBAR_MAX_LADDR = 255; - //! Most pessimistic time for a CHDR query to go to device and back - const double MPMD_CHDR_MAX_RTT = 0.02; - //! MPM Compatibility number - const std::vector<size_t> MPM_COMPAT_NUM = {1, 2}; +/************************************************************************* + * Local constants + ************************************************************************/ +const size_t MPMD_CROSSBAR_MAX_LADDR = 255; +//! Most pessimistic time for a CHDR query to go to device and back +const double MPMD_CHDR_MAX_RTT = 0.02; +//! MPM Compatibility number +const std::vector<size_t> MPM_COMPAT_NUM = {1, 2}; - /************************************************************************* - * Helper functions - ************************************************************************/ - void reset_time_synchronized(uhd::property_tree::sptr tree) - { - const size_t n_mboards = tree->list("/mboards").size(); - UHD_LOGGER_DEBUG("MPMD") - << "Synchronizing " << n_mboards <<" timekeepers..."; - auto get_time_last_pps = [tree](){ - return tree->access<time_spec_t>( - fs_path("/mboards/0/time/pps") - ).get(); - }; - auto end_time = std::chrono::steady_clock::now() - + std::chrono::milliseconds(1100); - auto time_last_pps = get_time_last_pps(); - UHD_LOG_DEBUG("MPMD", "Waiting for PPS clock edge..."); - while (time_last_pps == get_time_last_pps()) - { - if (std::chrono::steady_clock::now() > end_time) { - throw uhd::runtime_error( - "Board 0 may not be getting a PPS signal!\n" - "No PPS detected within the time interval.\n" - "See the application notes for your device.\n" - ); - } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - UHD_LOG_DEBUG("MPMD", "Setting all timekeepers to 0..."); - for (size_t mboard_idx = 0; mboard_idx < n_mboards; mboard_idx++) { - tree->access<time_spec_t>( - fs_path("/mboards") / mboard_idx / "time" / "pps" - ).set(time_spec_t(0.0)); +/************************************************************************* + * Helper functions + ************************************************************************/ +void reset_time_synchronized(uhd::property_tree::sptr tree) +{ + const size_t n_mboards = tree->list("/mboards").size(); + UHD_LOGGER_DEBUG("MPMD") << "Synchronizing " << n_mboards << " timekeepers..."; + auto get_time_last_pps = [tree]() { + return tree->access<time_spec_t>(fs_path("/mboards/0/time/pps")).get(); + }; + auto end_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(1100); + auto time_last_pps = get_time_last_pps(); + UHD_LOG_DEBUG("MPMD", "Waiting for PPS clock edge..."); + while (time_last_pps == get_time_last_pps()) { + if (std::chrono::steady_clock::now() > end_time) { + throw uhd::runtime_error("Board 0 may not be getting a PPS signal!\n" + "No PPS detected within the time interval.\n" + "See the application notes for your device.\n"); } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + UHD_LOG_DEBUG("MPMD", "Setting all timekeepers to 0..."); + for (size_t mboard_idx = 0; mboard_idx < n_mboards; mboard_idx++) { + tree->access<time_spec_t>(fs_path("/mboards") / mboard_idx / "time" / "pps") + .set(time_spec_t(0.0)); + } - UHD_LOG_DEBUG("MPMD", "Waiting for next PPS edge..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); + UHD_LOG_DEBUG("MPMD", "Waiting for next PPS edge..."); + std::this_thread::sleep_for(std::chrono::seconds(1)); - UHD_LOG_DEBUG("MPMD", "Verifying all timekeepers are aligned..."); - auto get_time_now = [tree](const size_t mb_index){ - return tree->access<time_spec_t>( - fs_path("/mboards") / mb_index / "time/now" - ).get(); - }; - for (size_t m = 1; m < n_mboards; m++){ - time_spec_t time_0 = get_time_now(0); - time_spec_t time_i = get_time_now(m); - if (time_i < time_0 - or (time_i - time_0) > time_spec_t(MPMD_CHDR_MAX_RTT)) { - UHD_LOGGER_WARNING("MULTI_USRP") << boost::format( - "Detected time deviation between board %d and board 0.\n" - "Board 0 time is %f seconds.\n" - "Board %d time is %f seconds.\n" - ) % m % time_0.get_real_secs() % m % time_i.get_real_secs(); - } + UHD_LOG_DEBUG("MPMD", "Verifying all timekeepers are aligned..."); + auto get_time_now = [tree](const size_t mb_index) { + return tree->access<time_spec_t>(fs_path("/mboards") / mb_index / "time/now") + .get(); + }; + for (size_t m = 1; m < n_mboards; m++) { + time_spec_t time_0 = get_time_now(0); + time_spec_t time_i = get_time_now(m); + if (time_i < time_0 or (time_i - time_0) > time_spec_t(MPMD_CHDR_MAX_RTT)) { + UHD_LOGGER_WARNING("MULTI_USRP") + << boost::format("Detected time deviation between board %d and board 0.\n" + "Board 0 time is %f seconds.\n" + "Board %d time is %f seconds.\n") + % m % time_0.get_real_secs() % m % time_i.get_real_secs(); } } +} - /*! Throw an exception if compat numbers don't match. - * - * \param component Name of the component for which we're checking the - * compat number (for logging and exceptions strings). - * \param expected Tuple of 2 integers representing MAJOR.MINOR compat - * number. - * \param actual Tuple of 2 integers representing MAJOR.MINOR compat - * number. - * \param advice_on_failure A string that is appended to the error message - * when compat number mismatches have occurred. - */ - void assert_compat_number_throw( - const std::string &component, - const std::vector<size_t> &expected, - const std::vector<size_t> &actual, - const std::string& advice_on_failure="" - ) { - UHD_ASSERT_THROW(expected.size() == 2); - UHD_ASSERT_THROW(actual.size() == 2); - UHD_LOGGER_TRACE("MPMD") - << "Checking " << component << " compat number. Expected: " - << expected[0] << "." << expected[1] - << " Actual: " - << actual[0] << "." << actual[1] - ; +/*! Throw an exception if compat numbers don't match. + * + * \param component Name of the component for which we're checking the + * compat number (for logging and exceptions strings). + * \param expected Tuple of 2 integers representing MAJOR.MINOR compat + * number. + * \param actual Tuple of 2 integers representing MAJOR.MINOR compat + * number. + * \param advice_on_failure A string that is appended to the error message + * when compat number mismatches have occurred. + */ +void assert_compat_number_throw(const std::string& component, + const std::vector<size_t>& expected, + const std::vector<size_t>& actual, + const std::string& advice_on_failure = "") +{ + UHD_ASSERT_THROW(expected.size() == 2); + UHD_ASSERT_THROW(actual.size() == 2); + UHD_LOGGER_TRACE("MPMD") << "Checking " << component + << " compat number. Expected: " << expected[0] << "." + << expected[1] << " Actual: " << actual[0] << "." + << actual[1]; - if (actual[0] != expected[0]) { - const std::string err_msg = - str(boost::format("%s major compat number mismatch. " - "Expected: %i.%i Actual: %i.%i.%s%s") - % component - % expected[0] % expected[1] - % actual[0] % actual[1] - % (advice_on_failure.empty() ? "" : " ") - % advice_on_failure); - UHD_LOG_ERROR("MPMD", err_msg); - throw uhd::runtime_error(err_msg); - } - if (actual[1] < expected[1]) { - const std::string err_msg = - str(boost::format("%s minor compat number mismatch. " - "Expected: %i.%i Actual: %i.%i.%s%s") - % component - % expected[0] % expected[1] - % actual[0] % actual[1] - % (advice_on_failure.empty() ? "" : " ") - % advice_on_failure); - UHD_LOG_ERROR("MPMD", err_msg); - throw uhd::runtime_error(err_msg); - } - if (actual[1] > expected[1]) { - const std::string err_msg = - str(boost::format("%s minor compat number mismatch. " - "Expected: %i.%i Actual: %i.%i") - % component - % expected[0] % expected[1] - % actual[0] % actual[1]); - UHD_LOG_WARNING("MPMD", err_msg); - } + if (actual[0] != expected[0]) { + const std::string err_msg = + str(boost::format("%s major compat number mismatch. " + "Expected: %i.%i Actual: %i.%i.%s%s") + % component % expected[0] % expected[1] % actual[0] % actual[1] + % (advice_on_failure.empty() ? "" : " ") % advice_on_failure); + UHD_LOG_ERROR("MPMD", err_msg); + throw uhd::runtime_error(err_msg); + } + if (actual[1] < expected[1]) { + const std::string err_msg = + str(boost::format("%s minor compat number mismatch. " + "Expected: %i.%i Actual: %i.%i.%s%s") + % component % expected[0] % expected[1] % actual[0] % actual[1] + % (advice_on_failure.empty() ? "" : " ") % advice_on_failure); + UHD_LOG_ERROR("MPMD", err_msg); + throw uhd::runtime_error(err_msg); + } + if (actual[1] > expected[1]) { + const std::string err_msg = + str(boost::format("%s minor compat number mismatch. " + "Expected: %i.%i Actual: %i.%i") + % component % expected[0] % expected[1] % actual[0] % actual[1]); + UHD_LOG_WARNING("MPMD", err_msg); } } +} // namespace /***************************************************************************** * Static class attributes ****************************************************************************/ -const std::string mpmd_impl::MPM_FINDALL_KEY = "find_all"; -const size_t mpmd_impl::MPM_DISCOVERY_PORT = 49600; -const std::string mpmd_impl::MPM_DISCOVERY_PORT_KEY = "discovery_port"; -const size_t mpmd_impl::MPM_RPC_PORT = 49601; -const std::string mpmd_impl::MPM_RPC_PORT_KEY = "rpc_port"; +const std::string mpmd_impl::MPM_FINDALL_KEY = "find_all"; +const size_t mpmd_impl::MPM_DISCOVERY_PORT = 49600; +const std::string mpmd_impl::MPM_DISCOVERY_PORT_KEY = "discovery_port"; +const size_t mpmd_impl::MPM_RPC_PORT = 49601; +const std::string mpmd_impl::MPM_RPC_PORT_KEY = "rpc_port"; const std::string mpmd_impl::MPM_RPC_GET_LAST_ERROR_CMD = "get_last_error"; -const std::string mpmd_impl::MPM_DISCOVERY_CMD = "MPM-DISC"; -const std::string mpmd_impl::MPM_ECHO_CMD = "MPM-ECHO"; +const std::string mpmd_impl::MPM_DISCOVERY_CMD = "MPM-DISC"; +const std::string mpmd_impl::MPM_ECHO_CMD = "MPM-ECHO"; /***************************************************************************** * Structors ****************************************************************************/ mpmd_impl::mpmd_impl(const device_addr_t& device_args) - : usrp::device3_impl() - , _device_args(device_args) + : usrp::device3_impl(), _device_args(device_args) { const device_addrs_t mb_args = separate_device_addr(device_args); - const size_t num_mboards = mb_args.size(); + const size_t num_mboards = mb_args.size(); _mb.reserve(num_mboards); const bool serialize_init = device_args.has_key("serialize_init"); - const bool skip_init = device_args.has_key("skip_init"); - UHD_LOGGER_INFO("MPMD") - << "Initializing " << num_mboards << " device(s) " - << (serialize_init ? "serially " : "in parallel ") - << "with args: " << device_args.to_string(); + const bool skip_init = device_args.has_key("skip_init"); + UHD_LOGGER_INFO("MPMD") << "Initializing " << num_mboards << " device(s) " + << (serialize_init ? "serially " : "in parallel ") + << "with args: " << device_args.to_string(); // First, claim all the devices (so we own them and no one else can claim // them). @@ -202,8 +179,8 @@ mpmd_impl::mpmd_impl(const device_addr_t& device_args) // can run _mb[*]->init() in parallel on all the _mb. // This can *not* be parallelized. std::vector<size_t> base_xport_addr(num_mboards, 2); // Starts at 2 [sic] - for (size_t mb_i = 0; mb_i < num_mboards-1; ++mb_i) { - base_xport_addr[mb_i+1] = base_xport_addr[mb_i] + _mb[mb_i]->num_xbars; + for (size_t mb_i = 0; mb_i < num_mboards - 1; ++mb_i) { + base_xport_addr[mb_i + 1] = base_xport_addr[mb_i] + _mb[mb_i]->num_xbars; } if (not skip_init) { @@ -260,35 +237,28 @@ mpmd_impl::~mpmd_impl() /***************************************************************************** * Private methods ****************************************************************************/ -mpmd_mboard_impl::uptr mpmd_impl::claim_and_make( - const uhd::device_addr_t& device_args -) { +mpmd_mboard_impl::uptr mpmd_impl::claim_and_make(const uhd::device_addr_t& device_args) +{ const std::string rpc_addr = device_args.get(xport::MGMT_ADDR_KEY); - UHD_LOGGER_DEBUG("MPMD") - << "Device args: `" << device_args.to_string() - << "'. RPC address: " << rpc_addr - ; + UHD_LOGGER_DEBUG("MPMD") << "Device args: `" << device_args.to_string() + << "'. RPC address: " << rpc_addr; if (rpc_addr.empty()) { UHD_LOG_ERROR("MPMD", "Could not determine RPC address from device args: " - << device_args.to_string()); + << device_args.to_string()); throw uhd::runtime_error("Could not determine device RPC address."); } return mpmd_mboard_impl::make(device_args, rpc_addr); } void mpmd_impl::setup_mb( - mpmd_mboard_impl *mb, - const size_t mb_index, - const size_t base_xport_addr -) { - assert_compat_number_throw( - "MPM", + mpmd_mboard_impl* mb, const size_t mb_index, const size_t base_xport_addr) +{ + assert_compat_number_throw("MPM", MPM_COMPAT_NUM, mb->rpc->request<std::vector<size_t>>("get_mpm_compat_num"), - "Please update the version of MPM on your USRP device." - ); + "Please update the version of MPM on your USRP device."); UHD_LOG_DEBUG("MPMD", "Initializing mboard " << mb_index); mb->init(); @@ -297,94 +267,83 @@ void mpmd_impl::setup_mb( } } -void mpmd_impl::setup_rfnoc_blocks( - mpmd_mboard_impl* mb, +void mpmd_impl::setup_rfnoc_blocks(mpmd_mboard_impl* mb, const size_t mb_index, - const uhd::device_addr_t& ctrl_xport_args -) { - UHD_LOG_TRACE("MPMD", - "Mboard " << mb_index << " reports " << mb->num_xbars << " crossbar(s)." - ); + const uhd::device_addr_t& ctrl_xport_args) +{ + UHD_LOG_TRACE( + "MPMD", "Mboard " << mb_index << " reports " << mb->num_xbars << " crossbar(s)."); // TODO: The args apply to all xbars, which may or may not be true for (size_t xbar_index = 0; xbar_index < mb->num_xbars; xbar_index++) { // Pull the number of blocks and base port from the args, if available. // Otherwise, get the values from MPM. - const size_t num_blocks = ctrl_xport_args.has_key("rfnoc_num_blocks") - ? ctrl_xport_args.cast<size_t>("rfnoc_num_blocks", 0) - : mb->rpc->request<size_t>("get_num_blocks", xbar_index); - const size_t base_port = ctrl_xport_args.has_key("rfnoc_base_port") - ? ctrl_xport_args.cast<size_t>("rfnoc_base_port", 0) - : mb->rpc->request<size_t>("get_base_port", xbar_index); + const size_t num_blocks = + ctrl_xport_args.has_key("rfnoc_num_blocks") + ? ctrl_xport_args.cast<size_t>("rfnoc_num_blocks", 0) + : mb->rpc->request<size_t>("get_num_blocks", xbar_index); + const size_t base_port = + ctrl_xport_args.has_key("rfnoc_base_port") + ? ctrl_xport_args.cast<size_t>("rfnoc_base_port", 0) + : mb->rpc->request<size_t>("get_base_port", xbar_index); const size_t local_addr = mb->get_xbar_local_addr(xbar_index); UHD_LOGGER_TRACE("MPMD") << "Enumerating RFNoC blocks for xbar " << xbar_index - << ". Total blocks: " << num_blocks - << " Base port: " << base_port - << " Local address: " << local_addr - ; - if (ctrl_xport_args.has_key("rfnoc_num_blocks") or - ctrl_xport_args.has_key("rfnoc_base_port")) { + << ". Total blocks: " << num_blocks << " Base port: " << base_port + << " Local address: " << local_addr; + if (ctrl_xport_args.has_key("rfnoc_num_blocks") + or ctrl_xport_args.has_key("rfnoc_base_port")) { // TODO: Remove this warning once we're confident this is // (relatively) safe and useful. Also add documentation to // usrp_n3xx.dox UHD_LOGGER_WARNING("MPMD") << "Overriding default RFNoC configuration. You are using an " << "experimental development feature, which may go away in " - << "future versions." - ; + << "future versions."; } try { - enumerate_rfnoc_blocks( - mb_index, - num_blocks, - base_port, - uhd::sid_t(0, 0, local_addr, 0), - ctrl_xport_args - ); - } catch (const std::exception &ex) { - UHD_LOGGER_ERROR("MPMD") - << "Failure during block enumeration: " - << ex.what(); + enumerate_rfnoc_blocks(mb_index, + num_blocks, + base_port, + uhd::sid_t(0, 0, local_addr, 0), + ctrl_xport_args); + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("MPMD") << "Failure during block enumeration: " << ex.what(); throw uhd::runtime_error("Failed to run enumerate_rfnoc_blocks()"); } } } void mpmd_impl::setup_rpc_blocks( - const device_addr_t &block_args, - const bool serialize_init -) { + const device_addr_t& block_args, const bool serialize_init) +{ std::vector<std::future<void>> task_list; // If we don't force async, most compilers, at least now, will default to // deferred. - const auto launch_policy = serialize_init ? - std::launch::deferred : - std::launch::async; + const auto launch_policy = serialize_init ? std::launch::deferred + : std::launch::async; // Preload all the tasks (they might start running on emplace_back) - for (const auto &block_ctrl: _rfnoc_block_ctrl) { + for (const auto& block_ctrl : _rfnoc_block_ctrl) { auto rpc_block_id = block_ctrl->get_block_id(); if (has_block<uhd::rfnoc::rpc_block_ctrl>(rpc_block_id)) { const size_t mboard_idx = rpc_block_id.get_device_no(); auto rpc_block_ctrl = get_block_ctrl<uhd::rfnoc::rpc_block_ctrl>(rpc_block_id); auto rpc_sptr = _mb[mboard_idx]->rpc; - task_list.emplace_back(std::async(launch_policy, - [rpc_block_id, rpc_block_ctrl, &block_args, rpc_sptr](){ + task_list.emplace_back(std::async( + launch_policy, [rpc_block_id, rpc_block_ctrl, &block_args, rpc_sptr]() { UHD_LOGGER_DEBUG("MPMD") << "Adding RPC access to block: " << rpc_block_id - << " Block args: " << block_args.to_string() - ; + << " Block args: " << block_args.to_string(); rpc_block_ctrl->set_rpc_client(rpc_sptr, block_args); - } - )); + })); } } // Execute all the calls to set_rpc_client(), either concurrently, or // serially - for (auto &task : task_list) { + for (auto& task : task_list) { task.get(); } } diff --git a/host/lib/usrp/mpmd/mpmd_impl.hpp b/host/lib/usrp/mpmd/mpmd_impl.hpp index e9d942c9d..f3328dc6f 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.hpp +++ b/host/lib/usrp/mpmd/mpmd_impl.hpp @@ -7,14 +7,14 @@ #ifndef INCLUDED_MPMD_IMPL_HPP #define INCLUDED_MPMD_IMPL_HPP -#include "mpmd_xport_mgr.hpp" #include "../device3/device3_impl.hpp" +#include "mpmd_xport_mgr.hpp" +#include <uhd/property_tree.hpp> #include <uhd/stream.hpp> +#include <uhd/transport/muxed_zero_copy_if.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/dict.hpp> #include <uhd/utils/tasks.hpp> -#include <uhd/transport/muxed_zero_copy_if.hpp> -#include <uhd/property_tree.hpp> #include <uhdlib/utils/rpc.hpp> #include <boost/optional.hpp> #include <map> @@ -24,16 +24,16 @@ * RPC timeout constants for MPMD ************************************************************************/ //! Time between reclaims (ms) -static constexpr size_t MPMD_RECLAIM_INTERVAL_MS = 1000; +static constexpr size_t MPMD_RECLAIM_INTERVAL_MS = 1000; //! Default timeout value for the init() RPC call (ms) -static constexpr size_t MPMD_DEFAULT_INIT_TIMEOUT = 120000; +static constexpr size_t MPMD_DEFAULT_INIT_TIMEOUT = 120000; //! Default timeout value for RPC calls (ms) -static constexpr size_t MPMD_DEFAULT_RPC_TIMEOUT = 2000; +static constexpr size_t MPMD_DEFAULT_RPC_TIMEOUT = 2000; //! Short timeout value for RPC calls (ms), used for calls that shouldn't // take long. This value can be used to quickly determine a link status. -static constexpr size_t MPMD_SHORT_RPC_TIMEOUT = 2000; +static constexpr size_t MPMD_SHORT_RPC_TIMEOUT = 2000; //! Claimer loop timeout value for RPC calls (ms). -static constexpr size_t MPMD_CLAIMER_RPC_TIMEOUT = 10000; +static constexpr size_t MPMD_CLAIMER_RPC_TIMEOUT = 10000; namespace uhd { namespace mpmd { @@ -41,9 +41,9 @@ namespace uhd { namespace mpmd { */ class mpmd_mboard_impl { - public: +public: /*** Types ***************************************************************/ - using uptr = std::unique_ptr<mpmd_mboard_impl>; + using uptr = std::unique_ptr<mpmd_mboard_impl>; using dev_info = std::map<std::string, std::string>; /*** Static helper *******************************************************/ @@ -53,8 +53,7 @@ class mpmd_mboard_impl * \param device_addr Device args. Must contain an mgmt_addr. */ static boost::optional<device_addr_t> is_device_reachable( - const device_addr_t& device_addr - ); + const device_addr_t& device_addr); /*** Structors ***********************************************************/ /*! Ctor: Claim device or throw an exception on failure. @@ -64,10 +63,7 @@ class mpmd_mboard_impl * \param mb_args Device args that pertain to this motherboard * \param ip_addr RPC client will attempt to connect to this IP address */ - mpmd_mboard_impl( - const uhd::device_addr_t &mb_args, - const std::string& ip_addr - ); + mpmd_mboard_impl(const uhd::device_addr_t& mb_args, const std::string& ip_addr); ~mpmd_mboard_impl(); /*** Factory *************************************************************/ @@ -75,10 +71,7 @@ class mpmd_mboard_impl * \param mb_args Device args that pertain to this motherboard * \param ip_addr RPC client will attempt to connect to this IP address */ - static uptr make( - const uhd::device_addr_t &mb_args, - const std::string& addr - ); + static uptr make(const uhd::device_addr_t& mb_args, const std::string& addr); /*** Init ****************************************************************/ void init(); @@ -112,7 +105,8 @@ class mpmd_mboard_impl void set_xbar_local_addr(const size_t xbar_index, const size_t local_addr); //! Return the local address of a given crossbar - size_t get_xbar_local_addr(const size_t xbar_index) const { + size_t get_xbar_local_addr(const size_t xbar_index) const + { return xbar_local_addrs.at(xbar_index); } @@ -126,11 +120,9 @@ class mpmd_mboard_impl // \param sid The full SID of this transport (UHD to device) // \param xport_type Transport type (CTRL, RX_DATA, ...) // \param args Any kind of args passed in via get_?x_stream() - uhd::both_xports_t make_transport( - const sid_t& sid, + uhd::both_xports_t make_transport(const sid_t& sid, usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& args - ); + const uhd::device_addr_t& args); size_t get_mtu(const uhd::direction_t dir) const; @@ -138,7 +130,7 @@ class mpmd_mboard_impl uhd::device_addr_t get_rx_hints() const; uhd::device_addr_t get_tx_hints() const; - private: +private: /*! Reference to the RPC client that handles claiming */ uhd::rpc_client::sptr _claim_rpc; @@ -152,21 +144,18 @@ class mpmd_mboard_impl */ bool claim(); - /*! Set RPC client timeout value - * - * \param timeout_ms time limit (in ms) that a rpc client waits for a single call - */ - void set_rpcc_timeout( - const uint64_t timeout_ms - ); + /*! Set RPC client timeout value + * + * \param timeout_ms time limit (in ms) that a rpc client waits for a single call + */ + void set_rpcc_timeout(const uint64_t timeout_ms); - uhd::task::sptr claim_device_and_make_task( - ); + uhd::task::sptr claim_device_and_make_task(); /*! Read out the log buffer from the MPM device and send it to native * logging system. */ - void dump_logs(const bool dump_to_null=false); + void dump_logs(const bool dump_to_null = false); /************************************************************************* * Private attributes @@ -224,10 +213,10 @@ public: * API ************************************************************************/ uhd::both_xports_t make_transport(const uhd::sid_t&, - uhd::usrp::device3_impl::xport_type_t, - const uhd::device_addr_t&); + uhd::usrp::device3_impl::xport_type_t, + const uhd::device_addr_t&); - private: +private: uhd::device_addr_t get_rx_hints(size_t mb_index); uhd::device_addr_t get_tx_hints(size_t mb_index); @@ -238,9 +227,7 @@ public: * * Does not initialize the device (see setup_mb() for that). */ - mpmd_mboard_impl::uptr claim_and_make( - const uhd::device_addr_t& dev_args - ); + mpmd_mboard_impl::uptr claim_and_make(const uhd::device_addr_t& dev_args); /*! Initialize a single motherboard * @@ -253,23 +240,15 @@ public: * */ void setup_mb( - mpmd_mboard_impl *mb, - const size_t mb_index, - const size_t base_xport_addr - ); + mpmd_mboard_impl* mb, const size_t mb_index, const size_t base_xport_addr); //! Setup all RFNoC blocks running on mboard \p mb_i void setup_rfnoc_blocks( - mpmd_mboard_impl* mb, - const size_t mb_i, - const uhd::device_addr_t& block_args - ); + mpmd_mboard_impl* mb, const size_t mb_i, const uhd::device_addr_t& block_args); //! Configure all blocks that require access to an RPC client void setup_rpc_blocks( - const uhd::device_addr_t &block_args, - const bool serialize_init - ); + const uhd::device_addr_t& block_args, const bool serialize_init); /*! Return the index of the motherboard given the local address of a * crossbar @@ -283,10 +262,7 @@ public: * \param mb Reference to the actual device */ static void init_property_tree( - uhd::property_tree::sptr tree, - fs_path mb_path, - mpmd_mboard_impl *mb - ); + uhd::property_tree::sptr tree, fs_path mb_path, mpmd_mboard_impl* mb); /************************************************************************* diff --git a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp index a49651f10..261b6f2aa 100644 --- a/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_mboard_impl.cpp @@ -5,209 +5,166 @@ // #include "mpmd_impl.hpp" -#include <uhd/utils/safe_call.hpp> -#include <uhd/utils/log.hpp> #include <uhd/transport/udp_simple.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/safe_call.hpp> #include <chrono> #include <thread> namespace { - /************************************************************************* - * Local constants - ************************************************************************/ - //! Timeout for pings (seconds). - constexpr double MPMD_PING_TIMEOUT = 0.1; - //! Default session ID (MPM will recognize a session by this name) - const std::string MPMD_DEFAULT_SESSION_ID = "UHD"; - //! Key to initialize a ping/measurement latency test - const std::string MPMD_MEAS_LATENCY_KEY = "measure_rpc_latency"; - //! Duration of a latency measurement test - constexpr size_t MPMD_MEAS_LATENCY_DURATION = 1000; - - using log_buf_t = std::vector<std::map<std::string, std::string>>; - - - /************************************************************************* - * Helper functions - ************************************************************************/ - /*! Return true if we can MPM ping a device via discovery service. - */ - bool is_pingable(const std::string& ip_addr, const std::string& udp_port) - { - auto udp = uhd::transport::udp_simple::make_broadcast( - ip_addr, - udp_port - ); - const std::string send_buf( - uhd::mpmd::mpmd_impl::MPM_ECHO_CMD + " ping" - ); - std::vector<uint8_t> recv_buf; - recv_buf.resize(send_buf.size(), ' '); - udp->send(boost::asio::buffer(send_buf.c_str(), send_buf.size())); - const size_t len = - udp->recv(boost::asio::buffer(recv_buf), MPMD_PING_TIMEOUT); - if (len == 0) { - UHD_LOG_TRACE("MPMD", - "Received no MPM ping, assuming device is unreachable."); - return false; - } - if (len != send_buf.size()) { - UHD_LOG_DEBUG("MPMD", - "Received bad return packet on MPM ping. Assuming endpoint" - " is not a valid MPM device."); - return false; - } - if (std::memcmp( - (void *) &recv_buf[0], - (void *) &send_buf[0], - send_buf.size()) != 0) { - UHD_LOG_DEBUG("MPMD", - "Received invalid return packet on MPM ping. Assuming endpoint" - " is not a valid MPM device."); - return false; - } - return true; +/************************************************************************* + * Local constants + ************************************************************************/ +//! Timeout for pings (seconds). +constexpr double MPMD_PING_TIMEOUT = 0.1; +//! Default session ID (MPM will recognize a session by this name) +const std::string MPMD_DEFAULT_SESSION_ID = "UHD"; +//! Key to initialize a ping/measurement latency test +const std::string MPMD_MEAS_LATENCY_KEY = "measure_rpc_latency"; +//! Duration of a latency measurement test +constexpr size_t MPMD_MEAS_LATENCY_DURATION = 1000; + +using log_buf_t = std::vector<std::map<std::string, std::string>>; + + +/************************************************************************* + * Helper functions + ************************************************************************/ +/*! Return true if we can MPM ping a device via discovery service. + */ +bool is_pingable(const std::string& ip_addr, const std::string& udp_port) +{ + auto udp = uhd::transport::udp_simple::make_broadcast(ip_addr, udp_port); + const std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD + " ping"); + std::vector<uint8_t> recv_buf; + recv_buf.resize(send_buf.size(), ' '); + udp->send(boost::asio::buffer(send_buf.c_str(), send_buf.size())); + const size_t len = udp->recv(boost::asio::buffer(recv_buf), MPMD_PING_TIMEOUT); + if (len == 0) { + UHD_LOG_TRACE("MPMD", "Received no MPM ping, assuming device is unreachable."); + return false; } - - /*! Call init() on an MPM device. - */ - void init_device( - uhd::rpc_client::sptr rpc, - const uhd::device_addr_t mb_args - ) { - auto init_status = - rpc->request_with_token<std::vector<std::string>>( - MPMD_DEFAULT_INIT_TIMEOUT, "get_init_status"); - if (init_status[0] != "true") { - throw uhd::runtime_error( - std::string("Device is in bad state: ") + init_status[1] - ); - } - - // TODO maybe put this somewhere else? - const std::set<std::string> key_blacklist{ - "serial", "claimed", "type", "rev", "addr" - }; - std::map<std::string, std::string> mpm_device_args; - for (const auto &key : mb_args.keys()) { - if (not key_blacklist.count(key)) { - mpm_device_args[key] = mb_args[key]; - } - } - if (not rpc->request_with_token<bool>(MPMD_DEFAULT_INIT_TIMEOUT, "init", mpm_device_args)) { - throw uhd::runtime_error("Failed to initialize device."); - } + if (len != send_buf.size()) { + UHD_LOG_DEBUG("MPMD", + "Received bad return packet on MPM ping. Assuming endpoint" + " is not a valid MPM device."); + return false; + } + if (std::memcmp((void*)&recv_buf[0], (void*)&send_buf[0], send_buf.size()) != 0) { + UHD_LOG_DEBUG("MPMD", + "Received invalid return packet on MPM ping. Assuming endpoint" + " is not a valid MPM device."); + return false; } + return true; +} - void measure_rpc_latency( - uhd::rpc_client::sptr rpc, - const size_t duration_ms=MPMD_MEAS_LATENCY_DURATION - ) { - const double alpha = 0.99; - const std::string payload = "1234567890"; - auto measure_once = [payload, rpc](){ - const auto start = std::chrono::steady_clock::now(); - rpc->request<std::string>("ping", payload); - return (double) std::chrono::duration_cast<std::chrono::microseconds>( - std::chrono::steady_clock::now() - start - ).count(); - }; +/*! Call init() on an MPM device. + */ +void init_device(uhd::rpc_client::sptr rpc, const uhd::device_addr_t mb_args) +{ + auto init_status = rpc->request_with_token<std::vector<std::string>>( + MPMD_DEFAULT_INIT_TIMEOUT, "get_init_status"); + if (init_status[0] != "true") { + throw uhd::runtime_error( + std::string("Device is in bad state: ") + init_status[1]); + } - double max_latency = measure_once(); - double avg_latency = max_latency; - - auto end_time = std::chrono::steady_clock::now() - + std::chrono::milliseconds(duration_ms); - size_t ctr = 1; - while (std::chrono::steady_clock::now() < end_time) { - const auto duration = measure_once(); - max_latency = std::max(max_latency, duration); - avg_latency = avg_latency * alpha + (1-alpha) * duration; - ctr++; - // Light throttle: - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + // TODO maybe put this somewhere else? + const std::set<std::string> key_blacklist{"serial", "claimed", "type", "rev", "addr"}; + std::map<std::string, std::string> mpm_device_args; + for (const auto& key : mb_args.keys()) { + if (not key_blacklist.count(key)) { + mpm_device_args[key] = mb_args[key]; } - - UHD_LOG_INFO("MPMD", - "RPC latency (coarse estimate): Avg = " << avg_latency << " us, " - "Max = " << max_latency - << ", n = " << ctr); } + if (not rpc->request_with_token<bool>( + MPMD_DEFAULT_INIT_TIMEOUT, "init", mpm_device_args)) { + throw uhd::runtime_error("Failed to initialize device."); + } +} - /*! Forward entries from a list of dictionaries to UHD's native logging - * system. - */ - void forward_logs(log_buf_t&& log_buf) - { - for (const auto &log_record : log_buf) { - if (log_record.count("levelname") == 0 or \ - log_record.count("message") == 0) { - UHD_LOG_ERROR("MPMD", - "Invalid logging structure returned from MPM device!"); - continue; - } - if (log_record.at("levelname") == "TRACE") { - UHD_LOG_TRACE( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "DEBUG") { - UHD_LOG_DEBUG( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "INFO") { - UHD_LOG_INFO( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "WARNING") { - UHD_LOG_WARNING( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "ERROR") { - UHD_LOG_ERROR( - log_record.at("name"), - log_record.at("message") - ); - } - else if (log_record.at("levelname") == "CRITICAL") { - UHD_LOG_FATAL( - log_record.at("name"), - log_record.at("message") - ); - } else { - UHD_LOG_ERROR("MPMD", - "Invalid log level returned from MPM device: " - "`" << log_record.at("levelname") << "'"); - } - } +void measure_rpc_latency( + uhd::rpc_client::sptr rpc, const size_t duration_ms = MPMD_MEAS_LATENCY_DURATION) +{ + const double alpha = 0.99; + const std::string payload = "1234567890"; + auto measure_once = [payload, rpc]() { + const auto start = std::chrono::steady_clock::now(); + rpc->request<std::string>("ping", payload); + return (double)std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::steady_clock::now() - start) + .count(); + }; + + double max_latency = measure_once(); + double avg_latency = max_latency; + + auto end_time = + std::chrono::steady_clock::now() + std::chrono::milliseconds(duration_ms); + size_t ctr = 1; + while (std::chrono::steady_clock::now() < end_time) { + const auto duration = measure_once(); + max_latency = std::max(max_latency, duration); + avg_latency = avg_latency * alpha + (1 - alpha) * duration; + ctr++; + // Light throttle: + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - /*! Return a new rpc_client with given addr and mb args - */ - uhd::rpc_client::sptr make_mpm_rpc_client( - const std::string& rpc_server_addr, - const uhd::device_addr_t& mb_args, - const size_t timeout_ms = MPMD_DEFAULT_RPC_TIMEOUT - ){ - return uhd::rpc_client::make( - rpc_server_addr, - mb_args.cast<size_t>( - uhd::mpmd::mpmd_impl::MPM_RPC_PORT_KEY, - uhd::mpmd::mpmd_impl::MPM_RPC_PORT - ), - timeout_ms, - uhd::mpmd::mpmd_impl::MPM_RPC_GET_LAST_ERROR_CMD); + UHD_LOG_INFO("MPMD", + "RPC latency (coarse estimate): Avg = " << avg_latency + << " us, " + "Max = " + << max_latency << ", n = " << ctr); +} + +/*! Forward entries from a list of dictionaries to UHD's native logging + * system. + */ +void forward_logs(log_buf_t&& log_buf) +{ + for (const auto& log_record : log_buf) { + if (log_record.count("levelname") == 0 or log_record.count("message") == 0) { + UHD_LOG_ERROR("MPMD", "Invalid logging structure returned from MPM device!"); + continue; + } + if (log_record.at("levelname") == "TRACE") { + UHD_LOG_TRACE(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "DEBUG") { + UHD_LOG_DEBUG(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "INFO") { + UHD_LOG_INFO(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "WARNING") { + UHD_LOG_WARNING(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "ERROR") { + UHD_LOG_ERROR(log_record.at("name"), log_record.at("message")); + } else if (log_record.at("levelname") == "CRITICAL") { + UHD_LOG_FATAL(log_record.at("name"), log_record.at("message")); + } else { + UHD_LOG_ERROR("MPMD", + "Invalid log level returned from MPM device: " + "`" << log_record.at("levelname") + << "'"); + } } +} +/*! Return a new rpc_client with given addr and mb args + */ +uhd::rpc_client::sptr make_mpm_rpc_client(const std::string& rpc_server_addr, + const uhd::device_addr_t& mb_args, + const size_t timeout_ms = MPMD_DEFAULT_RPC_TIMEOUT) +{ + return uhd::rpc_client::make(rpc_server_addr, + mb_args.cast<size_t>( + uhd::mpmd::mpmd_impl::MPM_RPC_PORT_KEY, uhd::mpmd::mpmd_impl::MPM_RPC_PORT), + timeout_ms, + uhd::mpmd::mpmd_impl::MPM_RPC_GET_LAST_ERROR_CMD); } +} // namespace + using namespace uhd; using namespace uhd::mpmd; @@ -215,22 +172,20 @@ using namespace uhd::mpmd; * Static Helpers *****************************************************************************/ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( - const device_addr_t &device_addr -) { - UHD_LOG_TRACE("MPMD", - "Checking accessibility of device `" << device_addr.to_string() - << "'"); + const device_addr_t& device_addr) +{ + UHD_LOG_TRACE( + "MPMD", "Checking accessibility of device `" << device_addr.to_string() << "'"); UHD_ASSERT_THROW(device_addr.has_key(xport::MGMT_ADDR_KEY)); const std::string rpc_addr = device_addr.get(xport::MGMT_ADDR_KEY); - const size_t rpc_port = device_addr.cast<size_t>( - mpmd_impl::MPM_RPC_PORT_KEY, - mpmd_impl::MPM_RPC_PORT - ); + const size_t rpc_port = + device_addr.cast<size_t>(mpmd_impl::MPM_RPC_PORT_KEY, mpmd_impl::MPM_RPC_PORT); auto rpcc = uhd::rpc_client::make(rpc_addr, rpc_port); // 1) Read back device info dev_info device_info_dict; try { - device_info_dict = rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); + device_info_dict = + rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); } catch (const uhd::runtime_error& e) { UHD_LOG_ERROR("MPMD", e.what()); } catch (...) { @@ -240,8 +195,8 @@ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( return boost::optional<device_addr_t>(); } // 2) Check for local device - if (device_info_dict.count("connection") and - device_info_dict.at("connection") == "local") { + if (device_info_dict.count("connection") + and device_info_dict.at("connection") == "local") { UHD_LOG_TRACE("MPMD", "Device is local, flagging as reachable."); return boost::optional<device_addr_t>(device_addr); } @@ -254,46 +209,43 @@ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( continue; } const std::string chdr_addr = device_info_dict.at(addr_key); - UHD_LOG_TRACE("MPMD", - "Checking reachability via network addr " << chdr_addr); + UHD_LOG_TRACE("MPMD", "Checking reachability via network addr " << chdr_addr); try { // First do an MPM ping -- there is some issue with rpclib that can // lead to indefinite timeouts - const std::string mpm_discovery_port = device_addr.get( - mpmd_impl::MPM_DISCOVERY_PORT_KEY, - std::to_string(mpmd_impl::MPM_DISCOVERY_PORT) - ); + const std::string mpm_discovery_port = + device_addr.get(mpmd_impl::MPM_DISCOVERY_PORT_KEY, + std::to_string(mpmd_impl::MPM_DISCOVERY_PORT)); if (!is_pingable(chdr_addr, mpm_discovery_port)) { - UHD_LOG_TRACE("MPMD", - "Cannot MPM ping, assuming device is unreachable."); + UHD_LOG_TRACE("MPMD", "Cannot MPM ping, assuming device is unreachable."); continue; } - UHD_LOG_TRACE("MPMD", - "Was able to ping device, trying RPC connection."); + UHD_LOG_TRACE("MPMD", "Was able to ping device, trying RPC connection."); auto chdr_rpcc = uhd::rpc_client::make(chdr_addr, rpc_port); - auto dev_info_chdr = chdr_rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); + auto dev_info_chdr = + chdr_rpcc->request<dev_info>(MPMD_SHORT_RPC_TIMEOUT, "get_device_info"); if (dev_info_chdr["serial"] != device_info_dict["serial"]) { - UHD_LOG_DEBUG("MPMD", boost::format( - "Connected to CHDR interface, but got wrong device. " - "Tried to reach serial %s, got %s") - % device_info_dict["serial"] % dev_info_chdr["serial"]); + UHD_LOG_DEBUG("MPMD", + boost::format("Connected to CHDR interface, but got wrong device. " + "Tried to reach serial %s, got %s") + % device_info_dict["serial"] % dev_info_chdr["serial"]); return boost::optional<device_addr_t>(); } else { - UHD_LOG_TRACE("MPMD", boost::format( - "Reachable device matches expected device (serial=%s)") - % device_info_dict["serial"] ); + UHD_LOG_TRACE("MPMD", + boost::format("Reachable device matches expected device (serial=%s)") + % device_info_dict["serial"]); } device_addr_t device_addr_copy = device_addr; - device_addr_copy["addr"] = chdr_addr; + device_addr_copy["addr"] = chdr_addr; return boost::optional<device_addr_t>(device_addr_copy); } catch (...) { - UHD_LOG_DEBUG("MPMD", - "Failed to reach device on network addr " << chdr_addr << "."); + UHD_LOG_DEBUG( + "MPMD", "Failed to reach device on network addr " << chdr_addr << "."); } } // If everything fails, we probably can't talk to this chap. - UHD_LOG_TRACE("MPMD", - "All reachability checks failed -- assuming device is not reachable."); + UHD_LOG_TRACE( + "MPMD", "All reachability checks failed -- assuming device is not reachable."); return boost::optional<device_addr_t>(); } @@ -301,9 +253,8 @@ boost::optional<device_addr_t> mpmd_mboard_impl::is_device_reachable( * Structors ****************************************************************************/ mpmd_mboard_impl::mpmd_mboard_impl( - const device_addr_t &mb_args_, - const std::string& rpc_server_addr -) : mb_args(mb_args_) + const device_addr_t& mb_args_, const std::string& rpc_server_addr) + : mb_args(mb_args_) , rpc(make_mpm_rpc_client(rpc_server_addr, mb_args_)) , num_xbars(rpc->request<size_t>("get_num_xbars")) , _claim_rpc(make_mpm_rpc_client(rpc_server_addr, mb_args, MPMD_CLAIMER_RPC_TIMEOUT)) @@ -311,12 +262,9 @@ mpmd_mboard_impl::mpmd_mboard_impl( , xbar_local_addrs(num_xbars, 0xFF) , _xport_mgr(xport::mpmd_xport_mgr::make(mb_args)) { - UHD_LOGGER_TRACE("MPMD") - << "Initializing mboard, connecting to RPC server address: " - << rpc_server_addr - << " mboard args: " << mb_args.to_string() - << " number of crossbars: " << num_xbars - ; + UHD_LOGGER_TRACE("MPMD") << "Initializing mboard, connecting to RPC server address: " + << rpc_server_addr << " mboard args: " << mb_args.to_string() + << " number of crossbars: " << num_xbars; _claimer_task = claim_device_and_make_task(); if (mb_args_.has_key(MPMD_MEAS_LATENCY_KEY)) { @@ -325,23 +273,21 @@ mpmd_mboard_impl::mpmd_mboard_impl( /// Get device info const auto device_info_dict = rpc->request<dev_info>("get_device_info"); - for (const auto &info_pair : device_info_dict) { + for (const auto& info_pair : device_info_dict) { device_info[info_pair.first] = info_pair.second; } - UHD_LOGGER_TRACE("MPMD") - << "MPM reports device info: " << device_info.to_string(); + UHD_LOGGER_TRACE("MPMD") << "MPM reports device info: " << device_info.to_string(); /// Get dboard info - const auto dboards_info = - rpc->request<std::vector<dev_info>>("get_dboard_info"); + const auto dboards_info = rpc->request<std::vector<dev_info>>("get_dboard_info"); UHD_ASSERT_THROW(this->dboard_info.size() == 0); - for (const auto &dboard_info_dict : dboards_info) { + for (const auto& dboard_info_dict : dboards_info) { uhd::device_addr_t this_db_info; - for (const auto &info_pair : dboard_info_dict) { + for (const auto& info_pair : dboard_info_dict) { this_db_info[info_pair.first] = info_pair.second; } UHD_LOGGER_TRACE("MPMD") - << "MPM reports dboard info for slot " << this->dboard_info.size() - << ": " << this_db_info.to_string(); + << "MPM reports dboard info for slot " << this->dboard_info.size() << ": " + << this_db_info.to_string(); this->dboard_info.push_back(this_db_info); } } @@ -353,11 +299,9 @@ mpmd_mboard_impl::~mpmd_mboard_impl() } catch (...) { UHD_LOG_WARNING("MPMD", "Could not flush log queue on exit!"); } - UHD_SAFE_CALL( - if (not rpc->request_with_token<bool>("unclaim")) { - UHD_LOG_WARNING("MPMD", "Failure to ack unclaim!"); - } - ); + UHD_SAFE_CALL(if (not rpc->request_with_token<bool>("unclaim")) { + UHD_LOG_WARNING("MPMD", "Failure to ack unclaim!"); + }); } /***************************************************************************** @@ -373,52 +317,42 @@ void mpmd_mboard_impl::init() * API ****************************************************************************/ void mpmd_mboard_impl::set_xbar_local_addr( - const size_t xbar_index, - const size_t local_addr -) { - UHD_ASSERT_THROW(rpc->request_with_token<bool>("set_xbar_local_addr", xbar_index, local_addr)); + const size_t xbar_index, const size_t local_addr) +{ + UHD_ASSERT_THROW( + rpc->request_with_token<bool>("set_xbar_local_addr", xbar_index, local_addr)); UHD_ASSERT_THROW(xbar_index < xbar_local_addrs.size()); xbar_local_addrs.at(xbar_index) = local_addr; } -uhd::both_xports_t mpmd_mboard_impl::make_transport( - const sid_t& sid, - usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args -) { - const std::string xport_type_str = [xport_type](){ +uhd::both_xports_t mpmd_mboard_impl::make_transport(const sid_t& sid, + usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& xport_args) +{ + const std::string xport_type_str = [xport_type]() { switch (xport_type) { - case mpmd_impl::CTRL: - return "CTRL"; - case mpmd_impl::ASYNC_MSG: - return "ASYNC_MSG"; - case mpmd_impl::RX_DATA: - return "RX_DATA"; - case mpmd_impl::TX_DATA: - return "TX_DATA"; - default: - UHD_THROW_INVALID_CODE_PATH(); + case mpmd_impl::CTRL: + return "CTRL"; + case mpmd_impl::ASYNC_MSG: + return "ASYNC_MSG"; + case mpmd_impl::RX_DATA: + return "RX_DATA"; + case mpmd_impl::TX_DATA: + return "TX_DATA"; + default: + UHD_THROW_INVALID_CODE_PATH(); }; }(); - UHD_LOGGER_TRACE("MPMD") - << __func__ << "(): Creating new transport of type: " - << xport_type_str - ; + UHD_LOGGER_TRACE("MPMD") << __func__ + << "(): Creating new transport of type: " << xport_type_str; using namespace uhd::mpmd::xport; const auto xport_info_list = rpc->request_with_token<mpmd_xport_mgr::xport_info_list_t>( - "request_xport", - sid.get_dst(), - sid.get_src(), - xport_type_str - ); - UHD_LOGGER_TRACE("MPMD") - << __func__ - << "(): request_xport() gave us " << xport_info_list.size() - << " option(s)." - ; + "request_xport", sid.get_dst(), sid.get_src(), xport_type_str); + UHD_LOGGER_TRACE("MPMD") << __func__ << "(): request_xport() gave us " + << xport_info_list.size() << " option(s)."; if (xport_info_list.empty()) { UHD_LOG_ERROR("MPMD", "No viable transport path found!"); throw uhd::runtime_error("No viable transport path found!"); @@ -426,15 +360,9 @@ uhd::both_xports_t mpmd_mboard_impl::make_transport( xport::mpmd_xport_mgr::xport_info_t xport_info_out; auto xports = _xport_mgr->make_transport( - xport_info_list, - xport_type, - xport_args, - xport_info_out - ); + xport_info_list, xport_type, xport_args, xport_info_out); - if (not rpc->request_with_token<bool>( - "commit_xport", - xport_info_out)) { + if (not rpc->request_with_token<bool>("commit_xport", xport_info_out)) { UHD_LOG_ERROR("MPMD", "Failed to create UDP transport!"); throw uhd::runtime_error("commit_xport() failed!"); } @@ -474,11 +402,10 @@ bool mpmd_mboard_impl::claim() } } -uhd::task::sptr mpmd_mboard_impl::claim_device_and_make_task( -) { - auto rpc_token = _claim_rpc->request<std::string>("claim", - mb_args.get("session_id", MPMD_DEFAULT_SESSION_ID) - ); +uhd::task::sptr mpmd_mboard_impl::claim_device_and_make_task() +{ + auto rpc_token = _claim_rpc->request<std::string>( + "claim", mb_args.get("session_id", MPMD_DEFAULT_SESSION_ID)); if (rpc_token.empty()) { throw uhd::value_error("mpmd device claiming failed!"); } @@ -493,8 +420,7 @@ uhd::task::sptr mpmd_mboard_impl::claim_device_and_make_task( }; this->dump_logs(); std::this_thread::sleep_until( - now + std::chrono::milliseconds(MPMD_RECLAIM_INTERVAL_MS) - ); + now + std::chrono::milliseconds(MPMD_RECLAIM_INTERVAL_MS)); }); } @@ -514,12 +440,10 @@ void mpmd_mboard_impl::dump_logs(const bool dump_to_null) * Factory ****************************************************************************/ mpmd_mboard_impl::uptr mpmd_mboard_impl::make( - const uhd::device_addr_t &mb_args, - const std::string& addr -) { + const uhd::device_addr_t& mb_args, const std::string& addr) +{ mpmd_mboard_impl::uptr mb = mpmd_mboard_impl::uptr(new mpmd_mboard_impl(mb_args, addr)); // implicit move return mb; } - diff --git a/host/lib/usrp/mpmd/mpmd_prop_tree.cpp b/host/lib/usrp/mpmd/mpmd_prop_tree.cpp index 27893341d..e4ebee5ac 100644 --- a/host/lib/usrp/mpmd/mpmd_prop_tree.cpp +++ b/host/lib/usrp/mpmd/mpmd_prop_tree.cpp @@ -9,91 +9,86 @@ #include "mpmd_impl.hpp" #include <uhd/property_tree.hpp> #include <uhd/types/component_file.hpp> -#include <uhd/types/sensors.hpp> #include <uhd/types/eeprom.hpp> +#include <uhd/types/sensors.hpp> #include <uhd/usrp/mboard_eeprom.hpp> using namespace uhd; using namespace uhd::mpmd; namespace { - //! Timeout value for the update_component RPC call (ms) - constexpr size_t MPMD_UPDATE_COMPONENT_TIMEOUT = 20000; +//! Timeout value for the update_component RPC call (ms) +constexpr size_t MPMD_UPDATE_COMPONENT_TIMEOUT = 20000; - /*! Update a component using all required files. For example, when updating the FPGA image - * (.bit or .bin), users can provide a new overlay image (DTS) to apply in addition. - * - * \param comps Vector of component files to be updated - * \param mb Reference to the actual device - */ - uhd::usrp::component_files_t _update_component( - const uhd::usrp::component_files_t& comps, - mpmd_mboard_impl *mb - ) { - // Construct the arguments to update component - std::vector<std::vector<uint8_t>> all_data; - std::vector<std::map<std::string, std::string>> all_metadata; - // Also construct a copy of just the metadata to store in the property tree - uhd::usrp::component_files_t all_comps_copy; +/*! Update a component using all required files. For example, when updating the FPGA image + * (.bit or .bin), users can provide a new overlay image (DTS) to apply in addition. + * + * \param comps Vector of component files to be updated + * \param mb Reference to the actual device + */ +uhd::usrp::component_files_t _update_component( + const uhd::usrp::component_files_t& comps, mpmd_mboard_impl* mb) +{ + // Construct the arguments to update component + std::vector<std::vector<uint8_t>> all_data; + std::vector<std::map<std::string, std::string>> all_metadata; + // Also construct a copy of just the metadata to store in the property tree + uhd::usrp::component_files_t all_comps_copy; - for (const auto& comp : comps) { - // Make a map for update components args - std::map<std::string, std::string> metadata; - // Make a component copy to add to the property tree - uhd::usrp::component_file_t comp_copy; - // Copy the metadata - for (const auto& key : comp.metadata.keys()) { - metadata[key] = comp.metadata[key]; - comp_copy.metadata[key] = comp.metadata[key]; - } - // Copy to the update component args - all_data.push_back(comp.data); - all_metadata.push_back(metadata); - // Copy to the property tree - all_comps_copy.push_back(comp_copy); + for (const auto& comp : comps) { + // Make a map for update components args + std::map<std::string, std::string> metadata; + // Make a component copy to add to the property tree + uhd::usrp::component_file_t comp_copy; + // Copy the metadata + for (const auto& key : comp.metadata.keys()) { + metadata[key] = comp.metadata[key]; + comp_copy.metadata[key] = comp.metadata[key]; } - - // Now call update component - const size_t update_component_timeout = MPMD_UPDATE_COMPONENT_TIMEOUT * comps.size(); - mb->rpc->notify_with_token(update_component_timeout, - "update_component", all_metadata, all_data); - return all_comps_copy; + // Copy to the update component args + all_data.push_back(comp.data); + all_metadata.push_back(metadata); + // Copy to the property tree + all_comps_copy.push_back(comp_copy); } - /* - * Query the device to get the metadata for desired component - * - * \param comp_name String component name - * \param mb Reference to the actual device - * \return component files containing the component metadata - */ - uhd::usrp::component_files_t _get_component_info( - const std::string &comp_name, - mpmd_mboard_impl *mb - ) { - UHD_LOG_TRACE("MPMD", "Getting component info for " << comp_name); - const auto component_metadata = mb->rpc->request<std::map<std::string, std::string>>( - "get_component_info", comp_name); - // Copy the contents of the component metadata into a object we can return - uhd::usrp::component_file_t return_component; - auto &return_metadata = return_component.metadata; - for (auto item : component_metadata) { - return_metadata[item.first] = item.second; - } - return uhd::usrp::component_files_t {return_component}; + // Now call update component + const size_t update_component_timeout = MPMD_UPDATE_COMPONENT_TIMEOUT * comps.size(); + mb->rpc->notify_with_token( + update_component_timeout, "update_component", all_metadata, all_data); + return all_comps_copy; +} + +/* + * Query the device to get the metadata for desired component + * + * \param comp_name String component name + * \param mb Reference to the actual device + * \return component files containing the component metadata + */ +uhd::usrp::component_files_t _get_component_info( + const std::string& comp_name, mpmd_mboard_impl* mb) +{ + UHD_LOG_TRACE("MPMD", "Getting component info for " << comp_name); + const auto component_metadata = mb->rpc->request<std::map<std::string, std::string>>( + "get_component_info", comp_name); + // Copy the contents of the component metadata into a object we can return + uhd::usrp::component_file_t return_component; + auto& return_metadata = return_component.metadata; + for (auto item : component_metadata) { + return_metadata[item.first] = item.second; } + return uhd::usrp::component_files_t{return_component}; } +} // namespace void mpmd_impl::init_property_tree( - uhd::property_tree::sptr tree, - fs_path mb_path, - mpmd_mboard_impl *mb -) { + uhd::property_tree::sptr tree, fs_path mb_path, mpmd_mboard_impl* mb) +{ /*** Device info ****************************************************/ if (not tree->exists("/name")) { - tree->create<std::string>("/name") - .set(mb->device_info.get("description", "Unknown MPM device")) - ; + tree->create<std::string>("/name").set( + mb->device_info.get("description", "Unknown MPM device")); } tree->create<std::string>(mb_path / "name") .set(mb->device_info.get("name", "UNKNOWN")); @@ -111,143 +106,98 @@ void mpmd_impl::init_property_tree( /*** Clocking *******************************************************/ tree->create<std::string>(mb_path / "clock_source/value") - .add_coerced_subscriber([mb](const std::string &clock_source){ - mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "set_clock_source", clock_source); + .add_coerced_subscriber([mb](const std::string& clock_source) { + mb->rpc->notify_with_token( + MPMD_DEFAULT_INIT_TIMEOUT, "set_clock_source", clock_source); }) - .set_publisher([mb](){ - return mb->rpc->request_with_token<std::string>( - "get_clock_source" - ); - }) - ; - tree->create<std::vector<std::string>>( - mb_path / "clock_source/options") - .set_publisher([mb](){ + .set_publisher([mb]() { + return mb->rpc->request_with_token<std::string>("get_clock_source"); + }); + tree->create<std::vector<std::string>>(mb_path / "clock_source/options") + .set_publisher([mb]() { return mb->rpc->request_with_token<std::vector<std::string>>( - "get_clock_sources" - ); - }) - ; + "get_clock_sources"); + }); tree->create<std::string>(mb_path / "time_source/value") - .add_coerced_subscriber([mb](const std::string &time_source){ - mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "set_time_source", time_source); + .add_coerced_subscriber([mb](const std::string& time_source) { + mb->rpc->notify_with_token( + MPMD_DEFAULT_INIT_TIMEOUT, "set_time_source", time_source); }) - .set_publisher([mb](){ - return mb->rpc->request_with_token<std::string>( - "get_time_source" - ); - }) - ; - tree->create<std::vector<std::string>>( - mb_path / "time_source/options") - .set_publisher([mb](){ + .set_publisher([mb]() { + return mb->rpc->request_with_token<std::string>("get_time_source"); + }); + tree->create<std::vector<std::string>>(mb_path / "time_source/options") + .set_publisher([mb]() { return mb->rpc->request_with_token<std::vector<std::string>>( - "get_time_sources" - ); - }) - ; + "get_time_sources"); + }); /*** Sensors ********************************************************/ auto sensor_list = - mb->rpc->request_with_token<std::vector<std::string>>( - "get_mb_sensors" - ); - UHD_LOG_DEBUG("MPMD", - "Found " << sensor_list.size() << " motherboard sensors." - ); + mb->rpc->request_with_token<std::vector<std::string>>("get_mb_sensors"); + UHD_LOG_DEBUG("MPMD", "Found " << sensor_list.size() << " motherboard sensors."); for (const auto& sensor_name : sensor_list) { - UHD_LOG_TRACE("MPMD", - "Adding motherboard sensor `" << sensor_name << "'" - ); - tree->create<sensor_value_t>( - mb_path / "sensors" / sensor_name) - .set_publisher([mb, sensor_name](){ + UHD_LOG_TRACE("MPMD", "Adding motherboard sensor `" << sensor_name << "'"); + tree->create<sensor_value_t>(mb_path / "sensors" / sensor_name) + .set_publisher([mb, sensor_name]() { auto sensor_val = sensor_value_t( mb->rpc->request_with_token<sensor_value_t::sensor_map_t>( - MPMD_DEFAULT_INIT_TIMEOUT, "get_mb_sensor", sensor_name - ) - ); + MPMD_DEFAULT_INIT_TIMEOUT, "get_mb_sensor", sensor_name)); return sensor_val; }) - .set_coercer([](const sensor_value_t &){ - throw uhd::runtime_error( - "Trying to write read-only sensor value!" - ); + .set_coercer([](const sensor_value_t&) { + throw uhd::runtime_error("Trying to write read-only sensor value!"); return sensor_value_t("", "", ""); - }) - ; + }); } /*** EEPROM *********************************************************/ tree->create<uhd::usrp::mboard_eeprom_t>(mb_path / "eeprom") - .add_coerced_subscriber([mb](const uhd::usrp::mboard_eeprom_t& mb_eeprom){ + .add_coerced_subscriber([mb](const uhd::usrp::mboard_eeprom_t& mb_eeprom) { eeprom_map_t eeprom_map; for (const auto& key : mb_eeprom.keys()) { - eeprom_map[key] = std::vector<uint8_t>( - mb_eeprom[key].cbegin(), - mb_eeprom[key].cend() - ); + eeprom_map[key] = + std::vector<uint8_t>(mb_eeprom[key].cbegin(), mb_eeprom[key].cend()); } - mb->rpc->notify_with_token(MPMD_DEFAULT_INIT_TIMEOUT, "set_mb_eeprom", eeprom_map); + mb->rpc->notify_with_token( + MPMD_DEFAULT_INIT_TIMEOUT, "set_mb_eeprom", eeprom_map); }) - .set_publisher([mb](){ + .set_publisher([mb]() { auto mb_eeprom = mb->rpc->request_with_token<std::map<std::string, std::string>>( - "get_mb_eeprom" - ); + "get_mb_eeprom"); uhd::usrp::mboard_eeprom_t mb_eeprom_dict( - mb_eeprom.cbegin(), mb_eeprom.cend() - ); + mb_eeprom.cbegin(), mb_eeprom.cend()); return mb_eeprom_dict; - }) - ; + }); /*** Updateable Components ******************************************/ std::vector<std::string> updateable_components = - mb->rpc->request<std::vector<std::string>>( - "list_updateable_components" - ); + mb->rpc->request<std::vector<std::string>>("list_updateable_components"); // TODO: Check the 'id' against the registered property UHD_LOG_DEBUG("MPMD", - "Found " << updateable_components.size() << " updateable motherboard components." - ); + "Found " << updateable_components.size() + << " updateable motherboard components."); for (const auto& comp_name : updateable_components) { - UHD_LOG_TRACE("MPMD", - "Adding motherboard component: " << comp_name); + UHD_LOG_TRACE("MPMD", "Adding motherboard component: " << comp_name); tree->create<uhd::usrp::component_files_t>(mb_path / "components" / comp_name) - .set_coercer([mb](const uhd::usrp::component_files_t& comp_files){ - return _update_component( - comp_files, - mb - ); + .set_coercer([mb](const uhd::usrp::component_files_t& comp_files) { + return _update_component(comp_files, mb); }) - .set_publisher([mb, comp_name](){ - return _get_component_info( - comp_name, - mb - ); - }) - ; // Done adding component to property tree + .set_publisher([mb, comp_name]() { + return _get_component_info(comp_name, mb); + }); // Done adding component to property tree } /*** MTUs ***********************************************************/ tree->create<size_t>(mb_path / "mtu/recv") - .add_coerced_subscriber([](const size_t){ - throw uhd::runtime_error( - "Attempting to write read-only value (MTU)!"); - }) - .set_publisher([mb](){ - return mb->get_mtu(uhd::RX_DIRECTION); + .add_coerced_subscriber([](const size_t) { + throw uhd::runtime_error("Attempting to write read-only value (MTU)!"); }) - ; + .set_publisher([mb]() { return mb->get_mtu(uhd::RX_DIRECTION); }); tree->create<size_t>(mb_path / "mtu/send") - .add_coerced_subscriber([](const size_t){ - throw uhd::runtime_error( - "Attempting to write read-only value (MTU)!"); + .add_coerced_subscriber([](const size_t) { + throw uhd::runtime_error("Attempting to write read-only value (MTU)!"); }) - .set_publisher([mb](){ - return mb->get_mtu(uhd::TX_DIRECTION); - }) - ; + .set_publisher([mb]() { return mb->get_mtu(uhd::TX_DIRECTION); }); } - diff --git a/host/lib/usrp/mpmd/mpmd_xport.cpp b/host/lib/usrp/mpmd/mpmd_xport.cpp index e697b6e80..3ef6a074c 100644 --- a/host/lib/usrp/mpmd/mpmd_xport.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport.cpp @@ -26,52 +26,37 @@ uhd::device_addr_t mpmd_impl::get_tx_hints(size_t mb_index) size_t mpmd_impl::identify_mboard_by_xbar_addr(const size_t xbar_addr) const { for (size_t mb_index = 0; mb_index < _mb.size(); mb_index++) { - for (size_t xbar_index = 0; - xbar_index < _mb[mb_index]->num_xbars; - xbar_index++) { + for (size_t xbar_index = 0; xbar_index < _mb[mb_index]->num_xbars; xbar_index++) { if (_mb.at(mb_index)->get_xbar_local_addr(xbar_index) == xbar_addr) { return mb_index; } } } - throw uhd::lookup_error(str( - boost::format("Cannot identify mboard for crossbar address %d") - % xbar_addr - )); + throw uhd::lookup_error( + str(boost::format("Cannot identify mboard for crossbar address %d") % xbar_addr)); } -both_xports_t mpmd_impl::make_transport( - const sid_t& dst_address, - usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& args -) { - const size_t mb_index = - identify_mboard_by_xbar_addr(dst_address.get_dst_addr()); +both_xports_t mpmd_impl::make_transport(const sid_t& dst_address, + usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& args) +{ + const size_t mb_index = identify_mboard_by_xbar_addr(dst_address.get_dst_addr()); - const sid_t sid( - 0, 0, // Not actually an address, more of an 'ignore me' value + const sid_t sid(0, + 0, // Not actually an address, more of an 'ignore me' value dst_address.get_dst_addr(), - dst_address.get_dst_endpoint() - ); - UHD_LOGGER_TRACE("MPMD") - << "Creating new transport to mboard: " << mb_index - << " SID: " << sid.to_pp_string_hex() - << " User-defined xport args: " << args.to_string() - ; - - both_xports_t xports = _mb[mb_index]->make_transport( - sid, - xport_type, - args - ); - UHD_LOGGER_TRACE("MPMD") - << "xport info: send_sid==" << xports.send_sid.to_pp_string_hex() - << " recv_sid==" << xports.recv_sid.to_pp_string_hex() - << " endianness==" - << (xports.endianness == uhd::ENDIANNESS_BIG ? "BE" : "LE") - << " recv_buff_size==" << xports.recv_buff_size - << " send_buff_size==" << xports.send_buff_size - ; + dst_address.get_dst_endpoint()); + UHD_LOGGER_TRACE("MPMD") << "Creating new transport to mboard: " << mb_index + << " SID: " << sid.to_pp_string_hex() + << " User-defined xport args: " << args.to_string(); + + both_xports_t xports = _mb[mb_index]->make_transport(sid, xport_type, args); + UHD_LOGGER_TRACE("MPMD") << "xport info: send_sid==" + << xports.send_sid.to_pp_string_hex() + << " recv_sid==" << xports.recv_sid.to_pp_string_hex() + << " endianness==" + << (xports.endianness == uhd::ENDIANNESS_BIG ? "BE" : "LE") + << " recv_buff_size==" << xports.recv_buff_size + << " send_buff_size==" << xports.send_buff_size; return xports; } - diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp index 78ffeaf1b..a7fff9262 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_base.hpp @@ -7,8 +7,8 @@ #ifndef INCLUDED_MPMD_XPORT_CTRL_BASE_HPP #define INCLUDED_MPMD_XPORT_CTRL_BASE_HPP -#include "mpmd_xport_mgr.hpp" #include "../device3/device3_impl.hpp" +#include "mpmd_xport_mgr.hpp" #include <uhd/types/device_addr.hpp> #include <memory> @@ -29,20 +29,14 @@ public: * \param xport_type CTRL, ASYNC_MSG, ... (see xport_type_t) * \param xport_args Additional arguments. These can come from the user. */ - virtual both_xports_t make_transport( - mpmd_xport_mgr::xport_info_t& xport_info, + virtual both_xports_t make_transport(mpmd_xport_mgr::xport_info_t& xport_info, const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args - ) = 0; + const uhd::device_addr_t& xport_args) = 0; //! Assert if an xport_info is even valid/feasible/available - virtual bool is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info - ) const = 0; + virtual bool is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const = 0; - virtual size_t get_mtu( - const uhd::direction_t dir - ) const = 0; + virtual size_t get_mtu(const uhd::direction_t dir) const = 0; }; }}} /* namespace uhd::mpmd::xport */ diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp index 13ecea5e9..7efe2bb9a 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp @@ -14,42 +14,41 @@ using namespace uhd::mpmd::xport; namespace { - //! Max frame size of a control packet in bytes - const size_t LIBERIO_CTRL_FRAME_MAX_SIZE = 128; - //! Max frame size of an async message packet in bytes - const size_t LIBERIO_ASYNC_FRAME_MAX_SIZE = 256; - //! Max frame size of a flow control packet in bytes - const size_t LIBERIO_FC_FRAME_MAX_SIZE = 64; - //! The max MTU will be this number times the page size - const size_t LIBERIO_PAGES_PER_BUF = 2; - //! Number of descriptors that liberio allocates (receive) - const size_t LIBERIO_NUM_RECV_FRAMES = 128; - //! Number of descriptors that liberio allocates (send) - const size_t LIBERIO_NUM_SEND_FRAMES = 128; - - uint32_t extract_sid_from_pkt(void* pkt, size_t) { - return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])) - .get_dst(); - } - +//! Max frame size of a control packet in bytes +const size_t LIBERIO_CTRL_FRAME_MAX_SIZE = 128; +//! Max frame size of an async message packet in bytes +const size_t LIBERIO_ASYNC_FRAME_MAX_SIZE = 256; +//! Max frame size of a flow control packet in bytes +const size_t LIBERIO_FC_FRAME_MAX_SIZE = 64; +//! The max MTU will be this number times the page size +const size_t LIBERIO_PAGES_PER_BUF = 2; +//! Number of descriptors that liberio allocates (receive) +const size_t LIBERIO_NUM_RECV_FRAMES = 128; +//! Number of descriptors that liberio allocates (send) +const size_t LIBERIO_NUM_SEND_FRAMES = 128; + +uint32_t extract_sid_from_pkt(void* pkt, size_t) +{ + return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])).get_dst(); } -mpmd_xport_ctrl_liberio::mpmd_xport_ctrl_liberio( - const uhd::device_addr_t& mb_args -) : _mb_args(mb_args) - , _recv_args(filter_args(mb_args, "recv")) - , _send_args(filter_args(mb_args, "send")) +} // namespace + +mpmd_xport_ctrl_liberio::mpmd_xport_ctrl_liberio(const uhd::device_addr_t& mb_args) + : _mb_args(mb_args) + , _recv_args(filter_args(mb_args, "recv")) + , _send_args(filter_args(mb_args, "send")) { // nop } -uhd::both_xports_t -mpmd_xport_ctrl_liberio::make_transport( - mpmd_xport_mgr::xport_info_t &xport_info, - const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& /*xport_args_*/ -) { +uhd::both_xports_t mpmd_xport_ctrl_liberio::make_transport( + mpmd_xport_mgr::xport_info_t& xport_info, + const usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& /*xport_args_*/ +) +{ transport::zero_copy_xport_params default_buff_args; /* default ones for RX / TX, override below */ @@ -75,8 +74,8 @@ mpmd_xport_ctrl_liberio::make_transport( both_xports_t xports; xports.endianness = uhd::ENDIANNESS_LITTLE; - xports.send_sid = sid_t(xport_info["send_sid"]); - xports.recv_sid = xports.send_sid.reversed(); + xports.send_sid = sid_t(xport_info["send_sid"]); + xports.recv_sid = xports.send_sid.reversed(); // this is kinda ghetto: scale buffer for muxed xports since we share the // buffer... @@ -87,7 +86,7 @@ mpmd_xport_ctrl_liberio::make_transport( divisor = 4; - //if (xport_info["muxed"] == "True") { + // if (xport_info["muxed"] == "True") { //// FIXME tbw //} if (xport_type == usrp::device3_impl::CTRL) { @@ -95,8 +94,8 @@ mpmd_xport_ctrl_liberio::make_transport( if (not _ctrl_dma_xport) { default_buff_args.send_frame_size = LIBERIO_CTRL_FRAME_MAX_SIZE; default_buff_args.recv_frame_size = LIBERIO_CTRL_FRAME_MAX_SIZE; - _ctrl_dma_xport = make_muxed_liberio_xport(tx_dev, rx_dev, - default_buff_args, int(divisor)); + _ctrl_dma_xport = + make_muxed_liberio_xport(tx_dev, rx_dev, default_buff_args, int(divisor)); } UHD_LOGGER_TRACE("MPMD") @@ -107,58 +106,52 @@ mpmd_xport_ctrl_liberio::make_transport( if (not _async_msg_dma_xport) { default_buff_args.send_frame_size = LIBERIO_ASYNC_FRAME_MAX_SIZE; default_buff_args.recv_frame_size = LIBERIO_ASYNC_FRAME_MAX_SIZE; - _async_msg_dma_xport = make_muxed_liberio_xport( - tx_dev, rx_dev, default_buff_args, int(divisor)); + _async_msg_dma_xport = + make_muxed_liberio_xport(tx_dev, rx_dev, default_buff_args, int(divisor)); } UHD_LOGGER_TRACE("MPMD") << "making (muxed) stream with num " << xports.recv_sid.get_dst(); - xports.recv = - _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst()); + xports.recv = _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst()); } else { - xports.recv = transport::liberio_zero_copy::make( - tx_dev, rx_dev, default_buff_args); + xports.recv = + transport::liberio_zero_copy::make(tx_dev, rx_dev, default_buff_args); } transport::udp_zero_copy::buff_params buff_params; - buff_params.recv_buff_size = - float(default_buff_args.recv_frame_size) * - float(default_buff_args.num_recv_frames) / divisor; - buff_params.send_buff_size = - float(default_buff_args.send_frame_size) * - float(default_buff_args.num_send_frames) / divisor; + buff_params.recv_buff_size = float(default_buff_args.recv_frame_size) + * float(default_buff_args.num_recv_frames) / divisor; + buff_params.send_buff_size = float(default_buff_args.send_frame_size) + * float(default_buff_args.num_send_frames) / divisor; // Finish both_xports_t object and return: xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; - xports.send = xports.recv; + xports.send = xports.recv; return xports; } bool mpmd_xport_ctrl_liberio::is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info -) const { + const mpmd_xport_mgr::xport_info_t& xport_info) const +{ return xport_info.at("type") == "liberio"; } -size_t mpmd_xport_ctrl_liberio::get_mtu( - const uhd::direction_t /* dir */ -) const { +size_t mpmd_xport_ctrl_liberio::get_mtu(const uhd::direction_t /* dir */ + ) const +{ return LIBERIO_PAGES_PER_BUF * getpagesize(); } uhd::transport::muxed_zero_copy_if::sptr -mpmd_xport_ctrl_liberio::make_muxed_liberio_xport( - const std::string &tx_dev, - const std::string &rx_dev, - const uhd::transport::zero_copy_xport_params &buff_args, - const size_t max_muxed_ports -) { - auto base_xport = transport::liberio_zero_copy::make( - tx_dev, rx_dev, buff_args); +mpmd_xport_ctrl_liberio::make_muxed_liberio_xport(const std::string& tx_dev, + const std::string& rx_dev, + const uhd::transport::zero_copy_xport_params& buff_args, + const size_t max_muxed_ports) +{ + auto base_xport = transport::liberio_zero_copy::make(tx_dev, rx_dev, buff_args); return uhd::transport::muxed_zero_copy_if::make( - base_xport, extract_sid_from_pkt, max_muxed_ports); + base_xport, extract_sid_from_pkt, max_muxed_ports); } - diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp index 9bea12aa3..5f635e7e7 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.hpp @@ -7,10 +7,10 @@ #ifndef INCLUDED_MPMD_XPORT_ctrl_liberio_HPP #define INCLUDED_MPMD_XPORT_ctrl_liberio_HPP -#include "mpmd_xport_ctrl_base.hpp" -#include <uhd/types/device_addr.hpp> #include "../device3/device3_impl.hpp" +#include "mpmd_xport_ctrl_base.hpp" #include <uhd/transport/muxed_zero_copy_if.hpp> +#include <uhd/types/device_addr.hpp> namespace uhd { namespace mpmd { namespace xport { @@ -19,34 +19,25 @@ namespace uhd { namespace mpmd { namespace xport { class mpmd_xport_ctrl_liberio : public mpmd_xport_ctrl_base { public: - mpmd_xport_ctrl_liberio( - const uhd::device_addr_t& mb_args - ); + mpmd_xport_ctrl_liberio(const uhd::device_addr_t& mb_args); /*! Open DMA interface to kernel (and thus to FPGA DMA engine) */ - both_xports_t make_transport( - mpmd_xport_mgr::xport_info_t& xport_info, + both_xports_t make_transport(mpmd_xport_mgr::xport_info_t& xport_info, const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args - ); + const uhd::device_addr_t& xport_args); - bool is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info - ) const; + bool is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const; - size_t get_mtu( - const uhd::direction_t dir - ) const ; + size_t get_mtu(const uhd::direction_t dir) const; private: /*! Create a muxed liberio transport for control packets */ uhd::transport::muxed_zero_copy_if::sptr make_muxed_liberio_xport( - const std::string &tx_dev, - const std::string &rx_dev, - const uhd::transport::zero_copy_xport_params &buff_args, - const size_t max_muxed_ports - ); + const std::string& tx_dev, + const std::string& rx_dev, + const uhd::transport::zero_copy_xport_params& buff_args, + const size_t max_muxed_ports); const uhd::device_addr_t _mb_args; const uhd::dict<std::string, std::string> _recv_args; diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp index ee48235ee..df02b183f 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.cpp @@ -4,12 +4,12 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "mpmd_xport_ctrl_udp.hpp" #include "mpmd_impl.hpp" #include "mpmd_xport_mgr.hpp" -#include "mpmd_xport_ctrl_udp.hpp" -#include <uhd/transport/udp_zero_copy.hpp> -#include <uhd/transport/udp_simple.hpp> #include <uhd/transport/udp_constants.hpp> +#include <uhd/transport/udp_simple.hpp> +#include <uhd/transport/udp_zero_copy.hpp> using namespace uhd; @@ -17,244 +17,216 @@ using namespace uhd::mpmd::xport; namespace { - #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) - //! Size of the host-side socket buffer for RX - const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x100000; // 1Mib - #elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) - //! Size of the host-side socket buffer for RX - // For an ~8k frame size any size >32MiB is just wasted buffer space - const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x2000000; // 32 MiB - #endif +#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) +//! Size of the host-side socket buffer for RX +const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x100000; // 1Mib +#elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) +//! Size of the host-side socket buffer for RX +// For an ~8k frame size any size >32MiB is just wasted buffer space +const size_t MPMD_RX_SW_BUFF_SIZE_ETH = 0x2000000; // 32 MiB +#endif - //! Maximum CHDR packet size in bytes - const size_t MPMD_10GE_DATA_FRAME_MAX_SIZE = 4000; +//! Maximum CHDR packet size in bytes +const size_t MPMD_10GE_DATA_FRAME_MAX_SIZE = 4000; - //! Maximum CHDR packet size in bytes - const size_t MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE = 1472; +//! Maximum CHDR packet size in bytes +const size_t MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE = 1472; - //! Number of send/recv frames - const size_t MPMD_ETH_NUM_FRAMES = 32; +//! Number of send/recv frames +const size_t MPMD_ETH_NUM_FRAMES = 32; - //! - const double MPMD_BUFFER_FILL_RATE = 20.0e-3; // s - //! For MTU discovery, the time we wait for a packet before calling it - // oversized (seconds). - const double MPMD_MTU_DISCOVERY_TIMEOUT = 0.02; +//! +const double MPMD_BUFFER_FILL_RATE = 20.0e-3; // s +//! For MTU discovery, the time we wait for a packet before calling it +// oversized (seconds). +const double MPMD_MTU_DISCOVERY_TIMEOUT = 0.02; - //TODO: move these to appropriate header file for all other devices - const size_t MAX_RATE_1GIGE = 1e9 / 8; // byte/s - const size_t MAX_RATE_10GIGE = 10e9 / 8; // byte/s +// TODO: move these to appropriate header file for all other devices +const size_t MAX_RATE_1GIGE = 1e9 / 8; // byte/s +const size_t MAX_RATE_10GIGE = 10e9 / 8; // byte/s - std::vector<std::string> get_addrs_from_mb_args( - const uhd::device_addr_t& mb_args - ) { - // mb_args must always include addr - if (not mb_args.has_key(FIRST_ADDR_KEY)) { - throw uhd::runtime_error("The " + FIRST_ADDR_KEY + " key must be specified in " - "device args to create an Ethernet transport to an RFNoC block"); - } - std::vector<std::string> addrs{mb_args[FIRST_ADDR_KEY]}; - if (mb_args.has_key(SECOND_ADDR_KEY)){ - addrs.push_back(mb_args[SECOND_ADDR_KEY]); - } - return addrs; +std::vector<std::string> get_addrs_from_mb_args(const uhd::device_addr_t& mb_args) +{ + // mb_args must always include addr + if (not mb_args.has_key(FIRST_ADDR_KEY)) { + throw uhd::runtime_error( + "The " + FIRST_ADDR_KEY + + " key must be specified in " + "device args to create an Ethernet transport to an RFNoC block"); } + std::vector<std::string> addrs{mb_args[FIRST_ADDR_KEY]}; + if (mb_args.has_key(SECOND_ADDR_KEY)) { + addrs.push_back(mb_args[SECOND_ADDR_KEY]); + } + return addrs; +} - /*! Do a binary search to discover MTU - * - * Uses the MPM echo service to figure out MTU. We simply send a bunch of - * packets and see if they come back until we converged on the path MTU. - * The end result must lie between \p min_frame_size and \p max_frame_size. - * - * \param address IP address - * \param port UDP port (yeah it's a string!) - * \param min_frame_size Minimum frame size, initialize algorithm to start - * with this value - * \param max_frame_size Maximum frame size, initialize algorithm to start - * with this value - * \param echo_timeout Timeout value in seconds. For frame sizes that - * exceed the MTU, we don't expect a response, and this - * is the amount of time we'll wait before we assume - * the frame size exceeds the MTU. - */ - size_t discover_mtu( - const std::string &address, - const std::string &port, - size_t min_frame_size, - size_t max_frame_size, - const double echo_timeout = 0.020 - ) { - const size_t echo_prefix_offset = - uhd::mpmd::mpmd_impl::MPM_ECHO_CMD.size(); - const size_t mtu_hdr_len = echo_prefix_offset + 10; - UHD_ASSERT_THROW(min_frame_size < max_frame_size); - UHD_ASSERT_THROW(min_frame_size % 4 == 0); - UHD_ASSERT_THROW(max_frame_size % 4 == 0); - UHD_ASSERT_THROW(min_frame_size >= echo_prefix_offset + mtu_hdr_len); - using namespace uhd::transport; - // The return port will probably differ from the discovery port, so we - // need a "broadcast" UDP connection; using make_connected() would - // drop packets - udp_simple::sptr udp = udp_simple::make_broadcast(address, port); - std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD); - send_buf.resize(max_frame_size, '#'); - UHD_ASSERT_THROW(send_buf.size() == max_frame_size); - std::vector<uint8_t> recv_buf; - recv_buf.resize(max_frame_size, ' '); - - // Little helper to check returned packets match the sent ones - auto require_bufs_match = [&recv_buf, &send_buf, mtu_hdr_len]( - const size_t len - ){ - if (len < mtu_hdr_len or std::memcmp( - (void *) &recv_buf[0], - (void *) &send_buf[0], - mtu_hdr_len - ) != 0) { - throw uhd::runtime_error("Unexpected content of MTU " - "discovery return packet!"); - } - }; - UHD_LOG_TRACE("MPMD", "Determining UDP MTU... "); - size_t seq_no = 0; - while (min_frame_size < max_frame_size) { - // Only test multiples of 4 bytes! - const size_t test_frame_size = - (max_frame_size/2 + min_frame_size/2 + 3) & ~size_t(3); - // Encode sequence number and current size in the string, makes it - // easy to debug in code or Wireshark. Is also used for identifying - // response packets. - std::sprintf( - &send_buf[echo_prefix_offset], - ";%04lu,%04lu", - seq_no++, - test_frame_size - ); - UHD_LOG_TRACE("MPMD", "Testing frame size " << test_frame_size); - udp->send(boost::asio::buffer(&send_buf[0], test_frame_size)); - - const size_t len = - udp->recv(boost::asio::buffer(recv_buf), echo_timeout); - if (len == 0) { - // Nothing received, so this is probably too big - max_frame_size = test_frame_size - 4; - } else if (len >= test_frame_size) { - // Size went through, so bump the minimum - require_bufs_match(len); - min_frame_size = test_frame_size; - } else if (len < test_frame_size) { - // This is an odd case. Something must have snipped the packet - // on the way back. Still, we'll just back off and try - // something smaller. - UHD_LOG_DEBUG("MPMD", - "Unexpected packet truncation during MTU discovery."); - require_bufs_match(len); - max_frame_size = len; - } +/*! Do a binary search to discover MTU + * + * Uses the MPM echo service to figure out MTU. We simply send a bunch of + * packets and see if they come back until we converged on the path MTU. + * The end result must lie between \p min_frame_size and \p max_frame_size. + * + * \param address IP address + * \param port UDP port (yeah it's a string!) + * \param min_frame_size Minimum frame size, initialize algorithm to start + * with this value + * \param max_frame_size Maximum frame size, initialize algorithm to start + * with this value + * \param echo_timeout Timeout value in seconds. For frame sizes that + * exceed the MTU, we don't expect a response, and this + * is the amount of time we'll wait before we assume + * the frame size exceeds the MTU. + */ +size_t discover_mtu(const std::string& address, + const std::string& port, + size_t min_frame_size, + size_t max_frame_size, + const double echo_timeout = 0.020) +{ + const size_t echo_prefix_offset = uhd::mpmd::mpmd_impl::MPM_ECHO_CMD.size(); + const size_t mtu_hdr_len = echo_prefix_offset + 10; + UHD_ASSERT_THROW(min_frame_size < max_frame_size); + UHD_ASSERT_THROW(min_frame_size % 4 == 0); + UHD_ASSERT_THROW(max_frame_size % 4 == 0); + UHD_ASSERT_THROW(min_frame_size >= echo_prefix_offset + mtu_hdr_len); + using namespace uhd::transport; + // The return port will probably differ from the discovery port, so we + // need a "broadcast" UDP connection; using make_connected() would + // drop packets + udp_simple::sptr udp = udp_simple::make_broadcast(address, port); + std::string send_buf(uhd::mpmd::mpmd_impl::MPM_ECHO_CMD); + send_buf.resize(max_frame_size, '#'); + UHD_ASSERT_THROW(send_buf.size() == max_frame_size); + std::vector<uint8_t> recv_buf; + recv_buf.resize(max_frame_size, ' '); + + // Little helper to check returned packets match the sent ones + auto require_bufs_match = [&recv_buf, &send_buf, mtu_hdr_len](const size_t len) { + if (len < mtu_hdr_len + or std::memcmp((void*)&recv_buf[0], (void*)&send_buf[0], mtu_hdr_len) != 0) { + throw uhd::runtime_error("Unexpected content of MTU " + "discovery return packet!"); + } + }; + UHD_LOG_TRACE("MPMD", "Determining UDP MTU... "); + size_t seq_no = 0; + while (min_frame_size < max_frame_size) { + // Only test multiples of 4 bytes! + const size_t test_frame_size = (max_frame_size / 2 + min_frame_size / 2 + 3) + & ~size_t(3); + // Encode sequence number and current size in the string, makes it + // easy to debug in code or Wireshark. Is also used for identifying + // response packets. + std::sprintf( + &send_buf[echo_prefix_offset], ";%04lu,%04lu", seq_no++, test_frame_size); + UHD_LOG_TRACE("MPMD", "Testing frame size " << test_frame_size); + udp->send(boost::asio::buffer(&send_buf[0], test_frame_size)); + + const size_t len = udp->recv(boost::asio::buffer(recv_buf), echo_timeout); + if (len == 0) { + // Nothing received, so this is probably too big + max_frame_size = test_frame_size - 4; + } else if (len >= test_frame_size) { + // Size went through, so bump the minimum + require_bufs_match(len); + min_frame_size = test_frame_size; + } else if (len < test_frame_size) { + // This is an odd case. Something must have snipped the packet + // on the way back. Still, we'll just back off and try + // something smaller. + UHD_LOG_DEBUG("MPMD", "Unexpected packet truncation during MTU discovery."); + require_bufs_match(len); + max_frame_size = len; } - UHD_LOG_DEBUG("MPMD", - "Path MTU for address " << address << ": " << min_frame_size); - return min_frame_size; } - + UHD_LOG_DEBUG("MPMD", "Path MTU for address " << address << ": " << min_frame_size); + return min_frame_size; } +} // namespace + -mpmd_xport_ctrl_udp::mpmd_xport_ctrl_udp( - const uhd::device_addr_t& mb_args -) : _mb_args(mb_args) - , _recv_args(filter_args(mb_args, "recv")) - , _send_args(filter_args(mb_args, "send")) - , _available_addrs(get_addrs_from_mb_args(mb_args)) - , _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE) +mpmd_xport_ctrl_udp::mpmd_xport_ctrl_udp(const uhd::device_addr_t& mb_args) + : _mb_args(mb_args) + , _recv_args(filter_args(mb_args, "recv")) + , _send_args(filter_args(mb_args, "send")) + , _available_addrs(get_addrs_from_mb_args(mb_args)) + , _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE) { const std::string mpm_discovery_port = _mb_args.get( - mpmd_impl::MPM_DISCOVERY_PORT_KEY, - std::to_string(mpmd_impl::MPM_DISCOVERY_PORT) - ); - auto discover_mtu_for_ip = [mpm_discovery_port](const std::string &ip_addr){ - return discover_mtu( - ip_addr, + mpmd_impl::MPM_DISCOVERY_PORT_KEY, std::to_string(mpmd_impl::MPM_DISCOVERY_PORT)); + auto discover_mtu_for_ip = [mpm_discovery_port](const std::string& ip_addr) { + return discover_mtu(ip_addr, mpm_discovery_port, - IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER, + IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER, MPMD_10GE_DATA_FRAME_MAX_SIZE, - MPMD_MTU_DISCOVERY_TIMEOUT - ); + MPMD_MTU_DISCOVERY_TIMEOUT); }; - for (const auto &ip_addr : _available_addrs) { + for (const auto& ip_addr : _available_addrs) { _mtu = std::min(_mtu, discover_mtu_for_ip(ip_addr)); } } -uhd::both_xports_t -mpmd_xport_ctrl_udp::make_transport( - mpmd_xport_mgr::xport_info_t &xport_info, - const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args_ -) { +uhd::both_xports_t mpmd_xport_ctrl_udp::make_transport( + mpmd_xport_mgr::xport_info_t& xport_info, + const usrp::device3_impl::xport_type_t xport_type, + const uhd::device_addr_t& xport_args_) +{ auto xport_args = xport_args_; if (xport_type == usrp::device3_impl::RX_DATA - and not xport_args.has_key("recv_buff_size")) { - xport_args["recv_buff_size"] = - std::to_string(MPMD_RX_SW_BUFF_SIZE_ETH); + and not xport_args.has_key("recv_buff_size")) { + xport_args["recv_buff_size"] = std::to_string(MPMD_RX_SW_BUFF_SIZE_ETH); } size_t link_speed = MAX_RATE_1GIGE; - if(xport_info.count("link_speed") == 0) - { + if (xport_info.count("link_speed") == 0) { UHD_LOG_WARNING("MPMD", "Could not determine link speed; using 1GibE max speed of " - << MAX_RATE_1GIGE); - } - else{ - link_speed = xport_info.at("link_speed") == "10000"? - MAX_RATE_10GIGE: - MAX_RATE_1GIGE; + << MAX_RATE_1GIGE); + } else { + link_speed = xport_info.at("link_speed") == "10000" ? MAX_RATE_10GIGE + : MAX_RATE_1GIGE; } transport::zero_copy_xport_params default_buff_args; // Create actual UDP transport default_buff_args.recv_frame_size = get_mtu(uhd::RX_DIRECTION); - default_buff_args.recv_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; - default_buff_args.send_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; + default_buff_args.recv_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; + default_buff_args.send_buff_size = link_speed * MPMD_BUFFER_FILL_RATE; if (xport_type == usrp::device3_impl::ASYNC_MSG) { default_buff_args.send_frame_size = MPMD_10GE_ASYNCMSG_FRAME_MAX_SIZE; - }else{ + } else { default_buff_args.send_frame_size = get_mtu(uhd::TX_DIRECTION); } transport::udp_zero_copy::buff_params buff_params; - auto recv = transport::udp_zero_copy::make( - xport_info["ipv4"], + auto recv = transport::udp_zero_copy::make(xport_info["ipv4"], xport_info["port"], default_buff_args, buff_params, - xport_args - ); - const uint16_t port = recv->get_local_port(); + xport_args); + const uint16_t port = recv->get_local_port(); const std::string src_ip_addr = recv->get_local_addr(); - xport_info["src_port"] = std::to_string(port); - xport_info["src_ipv4"] = src_ip_addr; + xport_info["src_port"] = std::to_string(port); + xport_info["src_ipv4"] = src_ip_addr; // Create both_xports_t object and finish: both_xports_t xports; - xports.endianness = uhd::ENDIANNESS_BIG; - xports.send_sid = sid_t(xport_info["send_sid"]); - xports.recv_sid = xports.send_sid.reversed(); + xports.endianness = uhd::ENDIANNESS_BIG; + xports.send_sid = sid_t(xport_info["send_sid"]); + xports.recv_sid = xports.send_sid.reversed(); xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; - xports.recv = recv; // Note: This is a type cast! - xports.send = recv; // This too + xports.recv = recv; // Note: This is a type cast! + xports.send = recv; // This too return xports; } -bool mpmd_xport_ctrl_udp::is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info -) const { +bool mpmd_xport_ctrl_udp::is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const +{ return std::find( - _available_addrs.cbegin(), - _available_addrs.cend(), - xport_info.at("ipv4") - ) != _available_addrs.cend(); + _available_addrs.cbegin(), _available_addrs.cend(), xport_info.at("ipv4")) + != _available_addrs.cend(); } size_t mpmd_xport_ctrl_udp::get_mtu(const uhd::direction_t /*dir*/) const diff --git a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp index ff7e69361..86301bb2a 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_ctrl_udp.hpp @@ -7,9 +7,9 @@ #ifndef INCLUDED_MPMD_XPORT_ctrl_udp_HPP #define INCLUDED_MPMD_XPORT_ctrl_udp_HPP +#include "../device3/device3_impl.hpp" #include "mpmd_xport_ctrl_base.hpp" #include <uhd/types/device_addr.hpp> -#include "../device3/device3_impl.hpp" namespace uhd { namespace mpmd { namespace xport { @@ -20,23 +20,15 @@ namespace uhd { namespace mpmd { namespace xport { class mpmd_xport_ctrl_udp : public mpmd_xport_ctrl_base { public: - mpmd_xport_ctrl_udp( - const uhd::device_addr_t& mb_args - ); + mpmd_xport_ctrl_udp(const uhd::device_addr_t& mb_args); - both_xports_t make_transport( - mpmd_xport_mgr::xport_info_t& xport_info, + both_xports_t make_transport(mpmd_xport_mgr::xport_info_t& xport_info, const usrp::device3_impl::xport_type_t xport_type, - const uhd::device_addr_t& xport_args - ); + const uhd::device_addr_t& xport_args); - bool is_valid( - const mpmd_xport_mgr::xport_info_t& xport_info - ) const; + bool is_valid(const mpmd_xport_mgr::xport_info_t& xport_info) const; - size_t get_mtu( - const uhd::direction_t dir - ) const; + size_t get_mtu(const uhd::direction_t dir) const; private: const uhd::device_addr_t _mb_args; diff --git a/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp b/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp index a4109b51d..c2200c66a 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp +++ b/host/lib/usrp/mpmd/mpmd_xport_mgr.cpp @@ -4,18 +4,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "mpmd_impl.hpp" #include "mpmd_xport_mgr.hpp" +#include "mpmd_impl.hpp" #include "mpmd_xport_ctrl_base.hpp" #include "mpmd_xport_ctrl_udp.hpp" #ifdef HAVE_LIBERIO -# include "mpmd_xport_ctrl_liberio.hpp" +# include "mpmd_xport_ctrl_liberio.hpp" #endif uhd::dict<std::string, std::string> uhd::mpmd::xport::filter_args( - const uhd::device_addr_t& args, - const std::string& prefix -) { + const uhd::device_addr_t& args, const std::string& prefix) +{ uhd::dict<std::string, std::string> filtered_args; for (const std::string& key : args.keys()) { if (key.find(prefix) != std::string::npos) { @@ -31,9 +30,7 @@ using namespace uhd::mpmd::xport; class mpmd_xport_mgr_impl : public mpmd_xport_mgr { public: - mpmd_xport_mgr_impl( - const uhd::device_addr_t& mb_args - ) : _mb_args(mb_args) + mpmd_xport_mgr_impl(const uhd::device_addr_t& mb_args) : _mb_args(mb_args) { // nop } @@ -41,36 +38,30 @@ public: /************************************************************************** * API (see mpmd_xport_mgr.hpp) *************************************************************************/ - uhd::both_xports_t make_transport( - const xport_info_list_t &xport_info_list, + uhd::both_xports_t make_transport(const xport_info_list_t& xport_info_list, const uhd::usrp::device3_impl::xport_type_t xport_type, const uhd::device_addr_t& xport_args, - xport_info_t& xport_info_out - ) { - for (const auto &xport_info : xport_info_list) { + xport_info_t& xport_info_out) + { + for (const auto& xport_info : xport_info_list) { require_xport_mgr(xport_info.at("type")); } // Run our incredibly smart selection algorithm - xport_info_out = select_xport_option(xport_info_list); + xport_info_out = select_xport_option(xport_info_list); const std::string xport_medium = xport_info_out.at("type"); - UHD_LOG_TRACE("MPMD", - __func__ << "(): xport medium is " << xport_medium); + UHD_LOG_TRACE("MPMD", __func__ << "(): xport medium is " << xport_medium); UHD_ASSERT_THROW(_xport_ctrls.count(xport_medium) > 0); UHD_ASSERT_THROW(_xport_ctrls.at(xport_medium)); // When we've picked our preferred option, pass it to the transport // implementation for execution: - return _xport_ctrls.at(xport_medium)->make_transport( - xport_info_out, - xport_type, - xport_args - ); + return _xport_ctrls.at(xport_medium) + ->make_transport(xport_info_out, xport_type, xport_args); } - size_t get_mtu( - const uhd::direction_t dir - ) const { + size_t get_mtu(const uhd::direction_t dir) const + { if (_xport_ctrls.empty()) { UHD_LOG_WARNING("MPMD", "Cannot determine MTU, no transport controls have been " @@ -79,7 +70,7 @@ public: } size_t mtu = ~size_t(0); - for (const auto &xport_ctrl_pair : _xport_ctrls) { + for (const auto& xport_ctrl_pair : _xport_ctrls) { mtu = std::min(mtu, xport_ctrl_pair.second->get_mtu(dir)); } @@ -99,21 +90,20 @@ private: * \returns One element of \p xport_info_list based on a selection * algorithm. */ - xport_info_t select_xport_option( - const xport_info_list_t &xport_info_list - ) const { + xport_info_t select_xport_option(const xport_info_list_t& xport_info_list) const + { for (const auto& xport_info : xport_info_list) { const std::string xport_medium = xport_info.at("type"); - if (_xport_ctrls.count(xport_medium) != 0 and - _xport_ctrls.at(xport_medium) and - _xport_ctrls.at(xport_medium)->is_valid(xport_info)) { + if (_xport_ctrls.count(xport_medium) != 0 and _xport_ctrls.at(xport_medium) + and _xport_ctrls.at(xport_medium)->is_valid(xport_info)) { return xport_info; } } - throw uhd::runtime_error("Could not select a transport option! " - "Either a transport hint was not specified or the specified " - "hint does not support communication with RFNoC blocks."); + throw uhd::runtime_error( + "Could not select a transport option! " + "Either a transport hint was not specified or the specified " + "hint does not support communication with RFNoC blocks."); } //! Create an instance of an xport manager implementation @@ -121,22 +111,17 @@ private: // \param xport_medium "UDP" or "liberio" // \param mb_args Device args mpmd_xport_ctrl_base::uptr make_mgr_impl( - const std::string &xport_medium, - const uhd::device_addr_t& mb_args - ) const { + const std::string& xport_medium, const uhd::device_addr_t& mb_args) const + { if (xport_medium == "UDP") { - return mpmd_xport_ctrl_base::uptr( - new mpmd_xport_ctrl_udp(mb_args) - ); + return mpmd_xport_ctrl_base::uptr(new mpmd_xport_ctrl_udp(mb_args)); #ifdef HAVE_LIBERIO } else if (xport_medium == "liberio") { - return mpmd_xport_ctrl_base::uptr( - new mpmd_xport_ctrl_liberio(mb_args) - ); + return mpmd_xport_ctrl_base::uptr(new mpmd_xport_ctrl_liberio(mb_args)); #endif } else { - UHD_LOG_WARNING("MPMD", - "Cannot instantiate transport medium " << xport_medium); + UHD_LOG_WARNING( + "MPMD", "Cannot instantiate transport medium " << xport_medium); return nullptr; } } @@ -150,11 +135,11 @@ private: // \param xport_medium Type of transport, e.g. "UDP", "liberio", ... // // \throws uhd::key_error if \p xport_medium is not known or registered - void require_xport_mgr(const std::string &xport_medium) + void require_xport_mgr(const std::string& xport_medium) { if (_xport_ctrls.count(xport_medium) == 0) { - UHD_LOG_TRACE("MPMD", - "Instantiating transport manager `" << xport_medium << "'"); + UHD_LOG_TRACE( + "MPMD", "Instantiating transport manager `" << xport_medium << "'"); auto mgr_impl = make_mgr_impl(xport_medium, _mb_args); if (mgr_impl) { _xport_ctrls[xport_medium] = std::move(mgr_impl); @@ -174,9 +159,7 @@ private: const uhd::device_addr_t _mb_args; }; -mpmd_xport_mgr::uptr mpmd_xport_mgr::make( - const uhd::device_addr_t& mb_args -) { +mpmd_xport_mgr::uptr mpmd_xport_mgr::make(const uhd::device_addr_t& mb_args) +{ return mpmd_xport_mgr::uptr(new mpmd_xport_mgr_impl(mb_args)); } - diff --git a/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp b/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp index 72700e69a..3d96e5ec6 100644 --- a/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp +++ b/host/lib/usrp/mpmd/mpmd_xport_mgr.hpp @@ -9,10 +9,10 @@ #include "../device3/device3_impl.hpp" #include <uhd/types/dict.hpp> -#include <memory> #include <map> -#include <vector> +#include <memory> #include <string> +#include <vector> namespace uhd { namespace mpmd { namespace xport { @@ -21,11 +21,11 @@ namespace uhd { namespace mpmd { namespace xport { */ //! Ethernet address for management and RPC communication -const std::string MGMT_ADDR_KEY = "mgmt_addr"; +const std::string MGMT_ADDR_KEY = "mgmt_addr"; //! Primary Ethernet address for streaming and RFNoC communication -const std::string FIRST_ADDR_KEY = "addr"; +const std::string FIRST_ADDR_KEY = "addr"; //! Secondary Ethernet address for streaming and RFNoC communication -const std::string SECOND_ADDR_KEY = "second_addr"; +const std::string SECOND_ADDR_KEY = "second_addr"; /*! Return filtered subset from a device_addr_t * @@ -36,9 +36,7 @@ const std::string SECOND_ADDR_KEY = "second_addr"; * \param prefix Key prefix to match against */ uhd::dict<std::string, std::string> filter_args( - const uhd::device_addr_t& args, - const std::string& prefix -); + const uhd::device_addr_t& args, const std::string& prefix); /*! MPMD Transport Manager * @@ -50,8 +48,8 @@ uhd::dict<std::string, std::string> filter_args( class mpmd_xport_mgr { public: - using uptr = std::unique_ptr<mpmd_xport_mgr>; - using xport_info_t = std::map<std::string, std::string>; + using uptr = std::unique_ptr<mpmd_xport_mgr>; + using xport_info_t = std::map<std::string, std::string>; using xport_info_list_t = std::vector<std::map<std::string, std::string>>; virtual ~mpmd_xport_mgr() {} @@ -65,9 +63,7 @@ public: * \throws uhd::key_error if \p xport_medium is not supported. The ctor of * the underlying class that is requested can also throw. */ - static uptr make( - const uhd::device_addr_t& mb_args - ); + static uptr make(const uhd::device_addr_t& mb_args); /*! Create a transports object * @@ -94,18 +90,14 @@ public: * The latter needs to get sent back to MPM to complete the * transport handshake. */ - virtual both_xports_t make_transport( - const xport_info_list_t &xport_info_list, + virtual both_xports_t make_transport(const xport_info_list_t& xport_info_list, const usrp::device3_impl::xport_type_t xport_type, const uhd::device_addr_t& xport_args, - xport_info_t& xport_info_out - ) = 0; + xport_info_t& xport_info_out) = 0; /*! Return the path MTU for whatever this manager lets us do */ - virtual size_t get_mtu( - const uhd::direction_t dir - ) const = 0; + virtual size_t get_mtu(const uhd::direction_t dir) const = 0; }; }}} /* namespace uhd::mpmd::xport */ diff --git a/host/lib/usrp/x300/x300_adc_ctrl.cpp b/host/lib/usrp/x300/x300_adc_ctrl.cpp index b8101753f..26c1d85ff 100644 --- a/host/lib/usrp/x300/x300_adc_ctrl.cpp +++ b/host/lib/usrp/x300/x300_adc_ctrl.cpp @@ -7,14 +7,15 @@ #include "x300_adc_ctrl.hpp" #include "ads62p48_regs.hpp" +#include <uhd/exception.hpp> #include <uhd/types/ranges.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> -#include <uhd/exception.hpp> using namespace uhd; -x300_adc_ctrl::~x300_adc_ctrl(void){ +x300_adc_ctrl::~x300_adc_ctrl(void) +{ /* NOP */ } @@ -24,26 +25,26 @@ x300_adc_ctrl::~x300_adc_ctrl(void){ class x300_adc_ctrl_impl : public x300_adc_ctrl { public: - x300_adc_ctrl_impl(uhd::spi_iface::sptr iface, const size_t slaveno): - _iface(iface), _slaveno(slaveno) + x300_adc_ctrl_impl(uhd::spi_iface::sptr iface, const size_t slaveno) + : _iface(iface), _slaveno(slaveno) { init(); } void init() { - //power-up adc - _ads62p48_regs.reset = 1; - this->send_ads62p48_reg(0x00); //issue a reset to the ADC - _ads62p48_regs.reset = 0; + // power-up adc + _ads62p48_regs.reset = 1; + this->send_ads62p48_reg(0x00); // issue a reset to the ADC + _ads62p48_regs.reset = 0; _ads62p48_regs.enable_low_speed_mode = 0; - _ads62p48_regs.ref = ads62p48_regs_t::REF_INTERNAL; - _ads62p48_regs.standby = ads62p48_regs_t::STANDBY_NORMAL; - _ads62p48_regs.power_down = ads62p48_regs_t::POWER_DOWN_NORMAL; - _ads62p48_regs.lvds_cmos = ads62p48_regs_t::LVDS_CMOS_DDR_LVDS; - _ads62p48_regs.channel_control = ads62p48_regs_t::CHANNEL_CONTROL_INDEPENDENT; - _ads62p48_regs.data_format = ads62p48_regs_t::DATA_FORMAT_2S_COMPLIMENT; + _ads62p48_regs.ref = ads62p48_regs_t::REF_INTERNAL; + _ads62p48_regs.standby = ads62p48_regs_t::STANDBY_NORMAL; + _ads62p48_regs.power_down = ads62p48_regs_t::POWER_DOWN_NORMAL; + _ads62p48_regs.lvds_cmos = ads62p48_regs_t::LVDS_CMOS_DDR_LVDS; + _ads62p48_regs.channel_control = ads62p48_regs_t::CHANNEL_CONTROL_INDEPENDENT; + _ads62p48_regs.data_format = ads62p48_regs_t::DATA_FORMAT_2S_COMPLIMENT; _ads62p48_regs.clk_out_pos_edge = ads62p48_regs_t::CLK_OUT_POS_EDGE_MINUS4_26; _ads62p48_regs.clk_out_neg_edge = ads62p48_regs_t::CLK_OUT_NEG_EDGE_MINUS4_26; @@ -67,7 +68,6 @@ public: this->send_ads62p48_reg(0x6a); this->send_ads62p48_reg(0x75); this->send_ads62p48_reg(0x76); - } void reset() @@ -75,31 +75,42 @@ public: init(); } - double set_gain(const double &gain) + double set_gain(const double& gain) { const meta_range_t gain_range = meta_range_t(0, 6.0, 0.5); - const int gain_bits = int((gain_range.clip(gain)*2.0) + 0.5); - _ads62p48_regs.gain_chA = gain_bits; - _ads62p48_regs.gain_chB = gain_bits; + const int gain_bits = int((gain_range.clip(gain) * 2.0) + 0.5); + _ads62p48_regs.gain_chA = gain_bits; + _ads62p48_regs.gain_chB = gain_bits; this->send_ads62p48_reg(0x55); this->send_ads62p48_reg(0x68); - return gain_bits/2; + return gain_bits / 2; } - void set_test_word(const std::string &patterna, const std::string &patternb, const uint32_t num) + void set_test_word( + const std::string& patterna, const std::string& patternb, const uint32_t num) { - _ads62p48_regs.custom_pattern_low = num & 0xff; + _ads62p48_regs.custom_pattern_low = num & 0xff; _ads62p48_regs.custom_pattern_high = num >> 8; - if (patterna == "ones") _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_ONES; - if (patterna == "zeros") _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_ZEROS; - if (patterna == "custom") _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_CUSTOM; - if (patterna == "ramp") _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_RAMP; - if (patterna == "normal") _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_NORMAL; - if (patternb == "ones") _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_ONES; - if (patternb == "zeros") _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_ZEROS; - if (patternb == "custom") _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_CUSTOM; - if (patterna == "ramp") _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_RAMP; - if (patterna == "normal") _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_NORMAL; + if (patterna == "ones") + _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_ONES; + if (patterna == "zeros") + _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_ZEROS; + if (patterna == "custom") + _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_CUSTOM; + if (patterna == "ramp") + _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_RAMP; + if (patterna == "normal") + _ads62p48_regs.test_patterns_chA = ads62p48_regs_t::TEST_PATTERNS_CHA_NORMAL; + if (patternb == "ones") + _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_ONES; + if (patternb == "zeros") + _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_ZEROS; + if (patternb == "custom") + _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_CUSTOM; + if (patterna == "ramp") + _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_RAMP; + if (patterna == "normal") + _ads62p48_regs.test_patterns_chB = ads62p48_regs_t::TEST_PATTERNS_CHB_NORMAL; this->send_ads62p48_reg(0x51); this->send_ads62p48_reg(0x52); this->send_ads62p48_reg(0x62); @@ -109,10 +120,7 @@ public: ~x300_adc_ctrl_impl(void) { _ads62p48_regs.power_down = ads62p48_regs_t::POWER_DOWN_GLOBAL; - UHD_SAFE_CALL - ( - this->send_ads62p48_reg(0x40); - ) + UHD_SAFE_CALL(this->send_ads62p48_reg(0x40);) } private: diff --git a/host/lib/usrp/x300/x300_adc_ctrl.hpp b/host/lib/usrp/x300/x300_adc_ctrl.hpp index eb29dd28f..106d79eed 100644 --- a/host/lib/usrp/x300/x300_adc_ctrl.hpp +++ b/host/lib/usrp/x300/x300_adc_ctrl.hpp @@ -27,9 +27,10 @@ public: */ static sptr make(uhd::spi_iface::sptr iface, const size_t slaveno); - virtual double set_gain(const double &) = 0; + virtual double set_gain(const double&) = 0; - virtual void set_test_word(const std::string &patterna, const std::string &patternb, const uint32_t = 0) = 0; + virtual void set_test_word( + const std::string& patterna, const std::string& patternb, const uint32_t = 0) = 0; virtual void reset(void) = 0; }; diff --git a/host/lib/usrp/x300/x300_clock_ctrl.cpp b/host/lib/usrp/x300/x300_clock_ctrl.cpp index 93e02ca7d..a867a9138 100644 --- a/host/lib/usrp/x300/x300_clock_ctrl.cpp +++ b/host/lib/usrp/x300/x300_clock_ctrl.cpp @@ -5,32 +5,43 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "lmk04816_regs.hpp" #include "x300_clock_ctrl.hpp" +#include "lmk04816_regs.hpp" #include "x300_defaults.hpp" -#include <uhd/utils/safe_call.hpp> #include <uhd/utils/math.hpp> +#include <uhd/utils/safe_call.hpp> #include <stdint.h> #include <boost/format.hpp> #include <boost/math/special_functions/round.hpp> -#include <stdexcept> #include <cmath> #include <cstdlib> +#include <stdexcept> -static const double X300_REF_CLK_OUT_RATE = 10e6; +static const double X300_REF_CLK_OUT_RATE = 10e6; static const uint16_t X300_MAX_CLKOUT_DIV = 1045; -constexpr double MIN_VCO_FREQ = 2370e6; -constexpr double MAX_VCO_FREQ = 2600e6; -constexpr double VCXO_FREQ = 96.0e6; // VCXO runs at 96MHz -constexpr int VCXO_PLL2_N = 2; // Assume that the PLL2 N predivider is set to /2. - -struct x300_clk_delays { - x300_clk_delays() : - fpga_dly_ns(0.0),adc_dly_ns(0.0),dac_dly_ns(0.0),db_rx_dly_ns(0.0),db_tx_dly_ns(0.0) - {} - x300_clk_delays(double fpga, double adc, double dac, double db_rx, double db_tx) : - fpga_dly_ns(fpga),adc_dly_ns(adc),dac_dly_ns(dac),db_rx_dly_ns(db_rx),db_tx_dly_ns(db_tx) - {} +constexpr double MIN_VCO_FREQ = 2370e6; +constexpr double MAX_VCO_FREQ = 2600e6; +constexpr double VCXO_FREQ = 96.0e6; // VCXO runs at 96MHz +constexpr int VCXO_PLL2_N = 2; // Assume that the PLL2 N predivider is set to /2. + +struct x300_clk_delays +{ + x300_clk_delays() + : fpga_dly_ns(0.0) + , adc_dly_ns(0.0) + , dac_dly_ns(0.0) + , db_rx_dly_ns(0.0) + , db_tx_dly_ns(0.0) + { + } + x300_clk_delays(double fpga, double adc, double dac, double db_rx, double db_tx) + : fpga_dly_ns(fpga) + , adc_dly_ns(adc) + , dac_dly_ns(dac) + , db_rx_dly_ns(db_rx) + , db_tx_dly_ns(db_tx) + { + } double fpga_dly_ns; double adc_dly_ns; @@ -51,14 +62,14 @@ static const x300_clk_delays X300_REV7_CLK_DELAYS = x300_clk_delays( using namespace uhd; using namespace uhd::math::fp_compare; -x300_clock_ctrl::~x300_clock_ctrl(void){ +x300_clock_ctrl::~x300_clock_ctrl(void) +{ /* NOP */ } -class x300_clock_ctrl_impl : public x300_clock_ctrl { - +class x300_clock_ctrl_impl : public x300_clock_ctrl +{ public: - ~x300_clock_ctrl_impl(void) {} x300_clock_ctrl_impl(uhd::spi_iface::sptr spiface, @@ -66,18 +77,19 @@ public: const size_t hw_rev, const double master_clock_rate, const double dboard_clock_rate, - const double system_ref_rate): - _spiface(spiface), - _slaveno(static_cast<int>(slaveno)), - _hw_rev(hw_rev), - _master_clock_rate(master_clock_rate), - _dboard_clock_rate(dboard_clock_rate), - _system_ref_rate(system_ref_rate) + const double system_ref_rate) + : _spiface(spiface) + , _slaveno(static_cast<int>(slaveno)) + , _hw_rev(hw_rev) + , _master_clock_rate(master_clock_rate) + , _dboard_clock_rate(dboard_clock_rate) + , _system_ref_rate(system_ref_rate) { init(); } - void reset_clocks() { + void reset_clocks() + { _lmk04816_regs.RESET = lmk04816_regs_t::RESET_RESET; this->write_regs(0); _lmk04816_regs.RESET = lmk04816_regs_t::RESET_NO_RESET; @@ -90,52 +102,56 @@ public: sync_clocks(); } - void sync_clocks(void) { - //soft sync: - //put the sync IO into output mode - FPGA must be input - //write low, then write high - this triggers a soft sync + void sync_clocks(void) + { + // soft sync: + // put the sync IO into output mode - FPGA must be input + // write low, then write high - this triggers a soft sync _lmk04816_regs.SYNC_POL_INV = lmk04816_regs_t::SYNC_POL_INV_SYNC_LOW; this->write_regs(11); _lmk04816_regs.SYNC_POL_INV = lmk04816_regs_t::SYNC_POL_INV_SYNC_HIGH; this->write_regs(11); } - double get_master_clock_rate(void) { + double get_master_clock_rate(void) + { return _master_clock_rate; } - double get_sysref_clock_rate(void) { + double get_sysref_clock_rate(void) + { return _system_ref_rate; } - double get_refout_clock_rate(void) { - //We support only one reference output rate + double get_refout_clock_rate(void) + { + // We support only one reference output rate return X300_REF_CLK_OUT_RATE; } - void set_dboard_rate(const x300_clock_which_t which, double rate) { - uint16_t div = uint16_t(_vco_freq / rate); - uint16_t *reg = NULL; - uint8_t addr = 0xFF; + void set_dboard_rate(const x300_clock_which_t which, double rate) + { + uint16_t div = uint16_t(_vco_freq / rate); + uint16_t* reg = NULL; + uint8_t addr = 0xFF; // Make sure requested rate is an even divisor of the VCO frequency if (not math::frequencies_are_equal(_vco_freq / div, rate)) throw uhd::value_error("invalid dboard rate requested"); - switch (which) - { - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - reg = &_lmk04816_regs.CLKout2_3_DIV; - addr = 1; - break; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - reg = &_lmk04816_regs.CLKout4_5_DIV; - addr = 2; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + reg = &_lmk04816_regs.CLKout2_3_DIV; + addr = 1; + break; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + reg = &_lmk04816_regs.CLKout4_5_DIV; + addr = 2; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } if (*reg == div) @@ -143,13 +159,15 @@ public: // Since the clock rate on one daughter board cannot be changed without // affecting the other daughter board, don't allow it. - throw uhd::not_implemented_error("x3xx set dboard clock rate does not support changing the clock rate"); + throw uhd::not_implemented_error( + "x3xx set dboard clock rate does not support changing the clock rate"); // This is open source code and users may need to enable this function // to support other daughterboards. If so, comment out the line above // that throws the error and allow the program to reach the code below. - // The LMK04816 datasheet says the register must be written twice if SYNC is enabled + // The LMK04816 datasheet says the register must be written twice if SYNC is + // enabled *reg = div; write_regs(addr); write_regs(addr); @@ -159,18 +177,17 @@ public: double get_dboard_rate(const x300_clock_which_t which) { double rate = 0.0; - switch (which) - { - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - rate = _vco_freq / _lmk04816_regs.CLKout2_3_DIV; - break; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - rate = _vco_freq / _lmk04816_regs.CLKout4_5_DIV; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + rate = _vco_freq / _lmk04816_regs.CLKout2_3_DIV; + break; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + rate = _vco_freq / _lmk04816_regs.CLKout4_5_DIV; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } return rate; } @@ -178,49 +195,63 @@ public: std::vector<double> get_dboard_rates(const x300_clock_which_t) { std::vector<double> rates; - for (size_t div = size_t(_vco_freq / _master_clock_rate); div <= X300_MAX_CLKOUT_DIV; div++) + for (size_t div = size_t(_vco_freq / _master_clock_rate); + div <= X300_MAX_CLKOUT_DIV; + div++) rates.push_back(_vco_freq / div); return rates; } void enable_dboard_clock(const x300_clock_which_t which, const bool enable) { - switch (which) - { - case X300_CLOCK_WHICH_DB0_RX: - if (enable != (_lmk04816_regs.CLKout2_TYPE == lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout2_TYPE = enable ? lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT2_TYPE_P_DOWN; - write_regs(6); - } - break; - case X300_CLOCK_WHICH_DB1_RX: - if (enable != (_lmk04816_regs.CLKout3_TYPE == lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout3_TYPE = enable ? lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT3_TYPE_P_DOWN; - write_regs(6); - } - break; - case X300_CLOCK_WHICH_DB0_TX: - if (enable != (_lmk04816_regs.CLKout5_TYPE == lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout5_TYPE = enable ? lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT5_TYPE_P_DOWN; - write_regs(7); - } - break; - case X300_CLOCK_WHICH_DB1_TX: - if (enable != (_lmk04816_regs.CLKout4_TYPE == lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout4_TYPE = enable ? lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT4_TYPE_P_DOWN; - write_regs(7); - } - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case X300_CLOCK_WHICH_DB0_RX: + if (enable + != (_lmk04816_regs.CLKout2_TYPE + == lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout2_TYPE = + enable ? lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT2_TYPE_P_DOWN; + write_regs(6); + } + break; + case X300_CLOCK_WHICH_DB1_RX: + if (enable + != (_lmk04816_regs.CLKout3_TYPE + == lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout3_TYPE = + enable ? lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT3_TYPE_P_DOWN; + write_regs(6); + } + break; + case X300_CLOCK_WHICH_DB0_TX: + if (enable + != (_lmk04816_regs.CLKout5_TYPE + == lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout5_TYPE = + enable ? lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT5_TYPE_P_DOWN; + write_regs(7); + } + break; + case X300_CLOCK_WHICH_DB1_TX: + if (enable + != (_lmk04816_regs.CLKout4_TYPE + == lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout4_TYPE = + enable ? lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT4_TYPE_P_DOWN; + write_regs(7); + } + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } - void set_ref_out(const bool enable) { + void set_ref_out(const bool enable) + { // TODO Implement divider configuration to allow for configurable output // rates if (enable) @@ -230,44 +261,48 @@ public: this->write_regs(8); } - void write_regs(uint8_t addr) { + void write_regs(uint8_t addr) + { uint32_t data = _lmk04816_regs.get_reg(addr); - _spiface->write_spi(_slaveno, spi_config_t::EDGE_RISE, data,32); + _spiface->write_spi(_slaveno, spi_config_t::EDGE_RISE, data, 32); } - double set_clock_delay(const x300_clock_which_t which, const double delay_ns, const bool resync = true) { - //All dividers have are delayed by 5 taps by default. The delay - //set by this function is relative to the 5 tap delay - static const uint16_t DDLY_MIN_TAPS = 5; - static const uint16_t DDLY_MAX_TAPS = 522; //Extended mode + double set_clock_delay( + const x300_clock_which_t which, const double delay_ns, const bool resync = true) + { + // All dividers have are delayed by 5 taps by default. The delay + // set by this function is relative to the 5 tap delay + static const uint16_t DDLY_MIN_TAPS = 5; + static const uint16_t DDLY_MAX_TAPS = 522; // Extended mode - //The resolution and range of the analog delay is fixed + // The resolution and range of the analog delay is fixed static const double ADLY_RES_NS = 0.025; static const double ADLY_MIN_NS = 0.500; static const double ADLY_MAX_NS = 0.975; - //Each digital tap delays the clock by one VCO period - double vco_period_ns = 1.0e9/_vco_freq; - double half_vco_period_ns = vco_period_ns/2.0; + // Each digital tap delays the clock by one VCO period + double vco_period_ns = 1.0e9 / _vco_freq; + double half_vco_period_ns = vco_period_ns / 2.0; - //Implement as much of the requested delay using digital taps. Whatever is leftover - //will be made up using the analog delay element and the half-cycle digital tap. - //A caveat here is that the analog delay starts at ADLY_MIN_NS, so we need to back off - //by that much when coming up with the digital taps so that the difference can be made - //up using the analog delay. + // Implement as much of the requested delay using digital taps. Whatever is + // leftover will be made up using the analog delay element and the half-cycle + // digital tap. A caveat here is that the analog delay starts at ADLY_MIN_NS, so + // we need to back off by that much when coming up with the digital taps so that + // the difference can be made up using the analog delay. uint16_t ddly_taps = 0; if (delay_ns < ADLY_MIN_NS) { - ddly_taps = static_cast<uint16_t>(std::floor((delay_ns)/vco_period_ns)); + ddly_taps = static_cast<uint16_t>(std::floor((delay_ns) / vco_period_ns)); } else { - ddly_taps = static_cast<uint16_t>(std::floor((delay_ns-ADLY_MIN_NS)/vco_period_ns)); + ddly_taps = static_cast<uint16_t>( + std::floor((delay_ns - ADLY_MIN_NS) / vco_period_ns)); } double leftover_delay = delay_ns - (vco_period_ns * ddly_taps); - //Compute settings - uint16_t ddly_value = ddly_taps + DDLY_MIN_TAPS; - bool adly_en = false; - uint8_t adly_value = 0; - uint8_t half_shift_en = 0; + // Compute settings + uint16_t ddly_value = ddly_taps + DDLY_MIN_TAPS; + bool adly_en = false; + uint8_t adly_value = 0; + uint8_t half_shift_en = 0; if (ddly_value > DDLY_MAX_TAPS) { throw uhd::value_error("set_clock_delay: Requested delay is out of range."); @@ -275,172 +310,203 @@ public: double coerced_delay = (vco_period_ns * ddly_taps); if (leftover_delay > ADLY_MAX_NS) { - //The VCO is running too slowly for us to compensate the digital delay difference using - //analog delay. Do the best we can. - adly_en = true; - adly_value = static_cast<uint8_t>(boost::math::round((ADLY_MAX_NS-ADLY_MIN_NS)/ADLY_RES_NS)); + // The VCO is running too slowly for us to compensate the digital delay + // difference using analog delay. Do the best we can. + adly_en = true; + adly_value = static_cast<uint8_t>( + boost::math::round((ADLY_MAX_NS - ADLY_MIN_NS) / ADLY_RES_NS)); coerced_delay += ADLY_MAX_NS; } else if (leftover_delay >= ADLY_MIN_NS && leftover_delay <= ADLY_MAX_NS) { - //The leftover delay can be compensated by the analog delay up to the analog delay resolution - adly_en = true; - adly_value = static_cast<uint8_t>(boost::math::round((leftover_delay-ADLY_MIN_NS)/ADLY_RES_NS)); - coerced_delay += ADLY_MIN_NS+(ADLY_RES_NS*adly_value); - } else if (leftover_delay >= (ADLY_MIN_NS - half_vco_period_ns) && leftover_delay < ADLY_MIN_NS) { - //The leftover delay if less than the minimum supported analog delay but if we move the digital - //delay back by half a VCO cycle then it will be in the range of the analog delay. So do that! - adly_en = true; - adly_value = static_cast<uint8_t>(boost::math::round((leftover_delay+half_vco_period_ns-ADLY_MIN_NS)/ADLY_RES_NS)); + // The leftover delay can be compensated by the analog delay up to the analog + // delay resolution + adly_en = true; + adly_value = static_cast<uint8_t>( + boost::math::round((leftover_delay - ADLY_MIN_NS) / ADLY_RES_NS)); + coerced_delay += ADLY_MIN_NS + (ADLY_RES_NS * adly_value); + } else if (leftover_delay >= (ADLY_MIN_NS - half_vco_period_ns) + && leftover_delay < ADLY_MIN_NS) { + // The leftover delay if less than the minimum supported analog delay but if + // we move the digital delay back by half a VCO cycle then it will be in the + // range of the analog delay. So do that! + adly_en = true; + adly_value = static_cast<uint8_t>(boost::math::round( + (leftover_delay + half_vco_period_ns - ADLY_MIN_NS) / ADLY_RES_NS)); half_shift_en = 1; - coerced_delay += ADLY_MIN_NS+(ADLY_RES_NS*adly_value)-half_vco_period_ns; + coerced_delay += + ADLY_MIN_NS + (ADLY_RES_NS * adly_value) - half_vco_period_ns; } else { - //Even after moving the digital delay back by half a cycle, we cannot make up the difference - //so give up on compensating for the difference from the digital delay tap. - //If control reaches here then the value of leftover_delay is possible very small and will still - //be close to what the client requested. + // Even after moving the digital delay back by half a cycle, we cannot make up + // the difference so give up on compensating for the difference from the + // digital delay tap. If control reaches here then the value of leftover_delay + // is possible very small and will still be close to what the client + // requested. } - UHD_LOG_DEBUG("X300", boost::format("x300_clock_ctrl::set_clock_delay: Which=%d, Requested=%f, Digital Taps=%d, Half Shift=%d, Analog Delay=%d (%s), Coerced Delay=%fns" - ) % which % delay_ns % ddly_value % (half_shift_en?"ON":"OFF") % ((int)adly_value) % (adly_en?"ON":"OFF") % coerced_delay) - - //Apply settings - switch (which) - { - case X300_CLOCK_WHICH_FPGA: - _lmk04816_regs.CLKout0_1_DDLY = ddly_value; - _lmk04816_regs.CLKout0_1_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout0_ADLY_SEL = lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout1_ADLY_SEL = lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout0_1_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout0_ADLY_SEL = lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout1_ADLY_SEL = lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_PD; - } - write_regs(0); - write_regs(6); - _delays.fpga_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - _lmk04816_regs.CLKout2_3_DDLY = ddly_value; - _lmk04816_regs.CLKout2_3_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout2_ADLY_SEL = lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout3_ADLY_SEL = lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout2_3_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout2_ADLY_SEL = lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout3_ADLY_SEL = lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_PD; - } - write_regs(1); - write_regs(6); - _delays.db_rx_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - _lmk04816_regs.CLKout4_5_DDLY = ddly_value; - _lmk04816_regs.CLKout4_5_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout4_ADLY_SEL = lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout5_ADLY_SEL = lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout4_5_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout4_ADLY_SEL = lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout5_ADLY_SEL = lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_PD; - } - write_regs(2); - write_regs(7); - _delays.db_tx_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_DAC0: - case X300_CLOCK_WHICH_DAC1: - _lmk04816_regs.CLKout6_7_DDLY = ddly_value; - _lmk04816_regs.CLKout6_7_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout6_ADLY_SEL = lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout7_ADLY_SEL = lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout6_7_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout6_ADLY_SEL = lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout7_ADLY_SEL = lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_PD; - } - write_regs(3); - write_regs(7); - _delays.dac_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_ADC0: - case X300_CLOCK_WHICH_ADC1: - _lmk04816_regs.CLKout8_9_DDLY = ddly_value; - _lmk04816_regs.CLKout8_9_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout8_ADLY_SEL = lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout9_ADLY_SEL = lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout8_9_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout8_ADLY_SEL = lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout9_ADLY_SEL = lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_PD; - } - write_regs(4); - write_regs(8); - _delays.adc_dly_ns = coerced_delay; - break; - default: - throw uhd::value_error("set_clock_delay: Requested source is invalid."); + UHD_LOG_DEBUG("X300", + boost::format( + "x300_clock_ctrl::set_clock_delay: Which=%d, Requested=%f, Digital " + "Taps=%d, Half Shift=%d, Analog Delay=%d (%s), Coerced Delay=%fns") + % which % delay_ns % ddly_value % (half_shift_en ? "ON" : "OFF") + % ((int)adly_value) % (adly_en ? "ON" : "OFF") % coerced_delay) + + // Apply settings + switch (which) { + case X300_CLOCK_WHICH_FPGA: + _lmk04816_regs.CLKout0_1_DDLY = ddly_value; + _lmk04816_regs.CLKout0_1_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout0_ADLY_SEL = + lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout1_ADLY_SEL = + lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout0_1_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout0_ADLY_SEL = + lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout1_ADLY_SEL = + lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_PD; + } + write_regs(0); + write_regs(6); + _delays.fpga_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + _lmk04816_regs.CLKout2_3_DDLY = ddly_value; + _lmk04816_regs.CLKout2_3_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout2_ADLY_SEL = + lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout3_ADLY_SEL = + lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout2_3_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout2_ADLY_SEL = + lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout3_ADLY_SEL = + lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_PD; + } + write_regs(1); + write_regs(6); + _delays.db_rx_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + _lmk04816_regs.CLKout4_5_DDLY = ddly_value; + _lmk04816_regs.CLKout4_5_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout4_ADLY_SEL = + lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout5_ADLY_SEL = + lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout4_5_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout4_ADLY_SEL = + lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout5_ADLY_SEL = + lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_PD; + } + write_regs(2); + write_regs(7); + _delays.db_tx_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_DAC0: + case X300_CLOCK_WHICH_DAC1: + _lmk04816_regs.CLKout6_7_DDLY = ddly_value; + _lmk04816_regs.CLKout6_7_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout6_ADLY_SEL = + lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout7_ADLY_SEL = + lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout6_7_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout6_ADLY_SEL = + lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout7_ADLY_SEL = + lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_PD; + } + write_regs(3); + write_regs(7); + _delays.dac_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_ADC0: + case X300_CLOCK_WHICH_ADC1: + _lmk04816_regs.CLKout8_9_DDLY = ddly_value; + _lmk04816_regs.CLKout8_9_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout8_ADLY_SEL = + lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout9_ADLY_SEL = + lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout8_9_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout8_ADLY_SEL = + lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout9_ADLY_SEL = + lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_PD; + } + write_regs(4); + write_regs(8); + _delays.adc_dly_ns = coerced_delay; + break; + default: + throw uhd::value_error("set_clock_delay: Requested source is invalid."); } - //Delays are applied only on a sync event - if (resync) sync_clocks(); + // Delays are applied only on a sync event + if (resync) + sync_clocks(); return coerced_delay; } - double get_clock_delay(const x300_clock_which_t which) { - switch (which) - { - case X300_CLOCK_WHICH_FPGA: - return _delays.fpga_dly_ns; - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - return _delays.db_rx_dly_ns; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - return _delays.db_tx_dly_ns; - case X300_CLOCK_WHICH_DAC0: - case X300_CLOCK_WHICH_DAC1: - return _delays.dac_dly_ns; - case X300_CLOCK_WHICH_ADC0: - case X300_CLOCK_WHICH_ADC1: - return _delays.adc_dly_ns; - default: - throw uhd::value_error("get_clock_delay: Requested source is invalid."); + double get_clock_delay(const x300_clock_which_t which) + { + switch (which) { + case X300_CLOCK_WHICH_FPGA: + return _delays.fpga_dly_ns; + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + return _delays.db_rx_dly_ns; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + return _delays.db_tx_dly_ns; + case X300_CLOCK_WHICH_DAC0: + case X300_CLOCK_WHICH_DAC1: + return _delays.dac_dly_ns; + case X300_CLOCK_WHICH_ADC0: + case X300_CLOCK_WHICH_ADC1: + return _delays.adc_dly_ns; + default: + throw uhd::value_error("get_clock_delay: Requested source is invalid."); } } private: - double autoset_pll2_config(const double output_freq) { // VCXO runs at 96MHz, assume PLL2 reference doubler is enabled const double ref = VCXO_FREQ * 2; const int lowest_vcodiv = static_cast<int>(std::ceil(MIN_VCO_FREQ / output_freq)); - const int highest_vcodiv = static_cast<int>(std::floor(MAX_VCO_FREQ / output_freq)); + const int highest_vcodiv = + static_cast<int>(std::floor(MAX_VCO_FREQ / output_freq)); // Find the PLL2 configuration with the lowest frequency error, favoring // higher phase comparison frequencies. - double best_error = 1e10; - double best_mcr = 0.0; + double best_error = 1e10; + double best_mcr = 0.0; double best_vco_freq = _vco_freq; - int best_N = _lmk04816_regs.PLL2_N_30; - int best_R = _lmk04816_regs.PLL2_R_28; + int best_N = _lmk04816_regs.PLL2_N_30; + int best_R = _lmk04816_regs.PLL2_R_28; for (int vcodiv = lowest_vcodiv; vcodiv <= highest_vcodiv; vcodiv++) { const double try_vco_freq = vcodiv * output_freq; // Start at R=2: with a min value of 2 for R, we don't have to worry // about exceeding the maximum phase comparison frequency for PLL2. - for (int r = 2; r <= 50; r++) - { + for (int r = 2; r <= 50; r++) { // Note: We could accomplish somewhat higher resolution if we change // the N predivider to odd values as well, and we may be able to get // better spur performance by balancing the predivider and the @@ -449,56 +515,60 @@ private: boost::math::round((r * try_vco_freq) / (VCXO_PLL2_N * ref))); const double actual_mcr = (ref * VCXO_PLL2_N * n) / (vcodiv * r); - const double error = std::abs(actual_mcr - output_freq); + const double error = std::abs(actual_mcr - output_freq); if (error < best_error) { - best_error = error; - best_mcr = actual_mcr; + best_error = error; + best_mcr = actual_mcr; best_vco_freq = try_vco_freq; - best_N = n; - best_R = r; + best_N = n; + best_R = r; } } } UHD_ASSERT_THROW(best_mcr > 0.0); - _vco_freq = best_vco_freq; + _vco_freq = best_vco_freq; _lmk04816_regs.PLL2_N_30 = best_N; _lmk04816_regs.PLL2_R_28 = best_R; _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; if (fp_compare_epsilon<double>(best_error) > 0.0) { UHD_LOGGER_WARNING("X300") - << boost::format("Attempted master clock rate %0.2f MHz, got %0.2f MHz") - % (output_freq / 1e6) % (best_mcr / 1e6); + << boost::format("Attempted master clock rate %0.2f MHz, got %0.2f MHz") + % (output_freq / 1e6) % (best_mcr / 1e6); } - UHD_LOGGER_TRACE("X300") << boost::format( - "Using automatic LMK04816 PLL2 config: N=%d, R=%d, VCO=%0.2f MHz, MCR=%0.2f MHz") - % _lmk04816_regs.PLL2_N_30 % _lmk04816_regs.PLL2_R_28 - % (_vco_freq / 1e6) % (best_mcr / 1e6); + UHD_LOGGER_TRACE("X300") + << boost::format("Using automatic LMK04816 PLL2 config: N=%d, R=%d, " + "VCO=%0.2f MHz, MCR=%0.2f MHz") + % _lmk04816_regs.PLL2_N_30 % _lmk04816_regs.PLL2_R_28 + % (_vco_freq / 1e6) % (best_mcr / 1e6); return best_mcr; } - void init() { + void init() + { /* The X3xx has two primary rates. The first is the * _system_ref_rate, which is sourced from the "clock_source"/"value" field - * of the property tree, and whose value can be 10e6, 11.52e6, 23.04e6, or 30.72e6. - * The _system_ref_rate is the input to the clocking system, and - * what comes out is a disciplined master clock running at the - * _master_clock_rate. As such, only certain combinations of - * system reference rates and master clock rates are supported. - * Additionally, a subset of these will operate in "zero delay" mode. */ - - enum opmode_t { INVALID, - m10M_200M_NOZDEL, // used for debug purposes only - m10M_200M_ZDEL, // Normal mode - m11_52M_184_32M_ZDEL, // LTE with 11.52 MHz ref - m23_04M_184_32M_ZDEL, // LTE with 23.04 MHz ref - m30_72M_184_32M_ZDEL, // LTE with external ref, aka CPRI Mode - m10M_184_32M_NOZDEL, // LTE with 10 MHz ref - m10M_120M_ZDEL, // NI USRP 120 MHz Clocking - m10M_AUTO_NOZDEL }; // automatic for arbitrary clock from 10MHz ref + * of the property tree, and whose value can be 10e6, 11.52e6, 23.04e6, + * or 30.72e6. The _system_ref_rate is the input to the clocking system, and what + * comes out is a disciplined master clock running at the _master_clock_rate. As + * such, only certain combinations of system reference rates and master clock + * rates are supported. Additionally, a subset of these will operate in "zero + * delay" mode. */ + + enum opmode_t { + INVALID, + m10M_200M_NOZDEL, // used for debug purposes only + m10M_200M_ZDEL, // Normal mode + m11_52M_184_32M_ZDEL, // LTE with 11.52 MHz ref + m23_04M_184_32M_ZDEL, // LTE with 23.04 MHz ref + m30_72M_184_32M_ZDEL, // LTE with external ref, aka CPRI Mode + m10M_184_32M_NOZDEL, // LTE with 10 MHz ref + m10M_120M_ZDEL, // NI USRP 120 MHz Clocking + m10M_AUTO_NOZDEL + }; // automatic for arbitrary clock from 10MHz ref /* The default clocking mode is 10MHz reference generating a 200 MHz master * clock, in zero-delay mode. */ @@ -515,61 +585,61 @@ private: } else if (math::frequencies_are_equal(_master_clock_rate, 120e6)) { /* 10MHz reference, 120 MHz master clock rate, Zero Delay */ clocking_mode = m10M_120M_ZDEL; - } else if ( - fp_compare_epsilon<double>(_master_clock_rate) >= uhd::usrp::x300::MIN_TICK_RATE - && fp_compare_epsilon<double>(_master_clock_rate) <= uhd::usrp::x300::MAX_TICK_RATE - ) { + } else if (fp_compare_epsilon<double>(_master_clock_rate) + >= uhd::usrp::x300::MIN_TICK_RATE + && fp_compare_epsilon<double>(_master_clock_rate) + <= uhd::usrp::x300::MAX_TICK_RATE) { /* 10MHz reference, attempt to automatically configure PLL * for arbitrary master clock rate, Zero Delay */ - UHD_LOGGER_WARNING("X300") - << "Using automatic master clock PLL config. This is an experimental feature."; + UHD_LOGGER_WARNING("X300") << "Using automatic master clock PLL config. " + "This is an experimental feature."; clocking_mode = m10M_AUTO_NOZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rates when using a %f MHz reference clock are:\n" - "120 MHz, 184.32 MHz and 200 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rates when using a %f MHz " + "reference clock are:\n" + "120 MHz, 184.32 MHz and 200 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else if (math::frequencies_are_equal(_system_ref_rate, 11.52e6)) { if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) { /* 11.52MHz reference, 184.32 MHz master clock out, Zero Delay */ clocking_mode = m11_52M_184_32M_ZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rate when using a %.2f MHz " + "reference clock is: 184.32 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else if (math::frequencies_are_equal(_system_ref_rate, 23.04e6)) { if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) { /* 11.52MHz reference, 184.32 MHz master clock out, Zero Delay */ clocking_mode = m23_04M_184_32M_ZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rate when using a %.2f MHz " + "reference clock is: 184.32 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else if (math::frequencies_are_equal(_system_ref_rate, 30.72e6)) { if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) { /* 30.72MHz reference, 184.32 MHz master clock out, Zero Delay */ clocking_mode = m30_72M_184_32M_ZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rate when using a %.2f MHz " + "reference clock is: 184.32 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else { - throw uhd::runtime_error(str( - boost::format("Invalid system reference rate: %.2f MHz.\nValid reference frequencies are: 10 MHz, 30.72 MHz.") - % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid system reference rate: %.2f MHz.\nValid " + "reference frequencies are: 10 MHz, 30.72 MHz.") + % (_system_ref_rate / 1e6))); } UHD_ASSERT_THROW(clocking_mode != INVALID); @@ -583,29 +653,29 @@ private: * architecture. Please refer to the datasheet for more information. */ switch (clocking_mode) { case m10M_200M_NOZDEL: - _vco_freq = 2400e6; + _vco_freq = 2400e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 48; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 48; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 48 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 25; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 4; + _lmk04816_regs.PLL2_N_30 = 25; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 4; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; break; case m10M_200M_ZDEL: - _vco_freq = 2400e6; + _vco_freq = 2400e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 5; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 5; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_1600UA; // PLL2 - 96 MHz compare frequency @@ -613,26 +683,28 @@ private: _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_5; _lmk04816_regs.PLL2_R_28 = 2; - if(_hw_rev <= 4) - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; + if (_hw_rev <= 4) + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; else - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; break; case m10M_184_32M_NOZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 48; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 48; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_4KILO_OHM; @@ -644,18 +716,18 @@ private: break; case m11_52M_184_32M_ZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 1.92 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 6; - _lmk04816_regs.PLL1_R_27 = 6; + _lmk04816_regs.PLL1_N_28 = 6; + _lmk04816_regs.PLL1_R_27 = 6; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_1KILO_OHM; @@ -667,18 +739,18 @@ private: break; case m23_04M_184_32M_ZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 1.92 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 12; - _lmk04816_regs.PLL1_R_27 = 12; + _lmk04816_regs.PLL1_N_28 = 12; + _lmk04816_regs.PLL1_R_27 = 12; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_1KILO_OHM; @@ -690,18 +762,18 @@ private: break; case m30_72M_184_32M_ZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 2.048 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 15; - _lmk04816_regs.PLL1_R_27 = 15; + _lmk04816_regs.PLL1_N_28 = 15; + _lmk04816_regs.PLL1_R_27 = 15; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_1KILO_OHM; @@ -713,12 +785,12 @@ private: break; case m10M_120M_ZDEL: - _vco_freq = 2400e6; + _vco_freq = 2400e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 5; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 5; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 96 MHz compare frequency @@ -726,10 +798,12 @@ private: _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_5; _lmk04816_regs.PLL2_R_28 = 2; - if(_hw_rev <= 4) - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; + if (_hw_rev <= 4) + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; else - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; break; @@ -737,8 +811,8 @@ private: _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT; // PLL1 - 2MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 48; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 48; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - this call will set _vco_freq and PLL2 P/N/R registers. @@ -751,11 +825,11 @@ private: break; }; - uint16_t master_clock_div = static_cast<uint16_t>( - std::ceil(_vco_freq / _master_clock_rate)); + uint16_t master_clock_div = + static_cast<uint16_t>(std::ceil(_vco_freq / _master_clock_rate)); - uint16_t dboard_div = static_cast<uint16_t>( - std::ceil(_vco_freq / _dboard_clock_rate)); + uint16_t dboard_div = + static_cast<uint16_t>(std::ceil(_vco_freq / _dboard_clock_rate)); /* Reset the LMK clock controller. */ _lmk04816_regs.RESET = lmk04816_regs_t::RESET_RESET; @@ -770,13 +844,13 @@ private: this->write_regs(0); // Register 1 - _lmk04816_regs.CLKout2_3_PD = lmk04816_regs_t::CLKOUT2_3_PD_POWER_UP; + _lmk04816_regs.CLKout2_3_PD = lmk04816_regs_t::CLKOUT2_3_PD_POWER_UP; _lmk04816_regs.CLKout2_3_DIV = dboard_div; // Register 2 - _lmk04816_regs.CLKout4_5_PD = lmk04816_regs_t::CLKOUT4_5_PD_POWER_UP; + _lmk04816_regs.CLKout4_5_PD = lmk04816_regs_t::CLKOUT4_5_PD_POWER_UP; _lmk04816_regs.CLKout4_5_DIV = dboard_div; // Register 3 - _lmk04816_regs.CLKout6_7_DIV = master_clock_div; + _lmk04816_regs.CLKout6_7_DIV = master_clock_div; _lmk04816_regs.CLKout6_7_OSCin_Sel = lmk04816_regs_t::CLKOUT6_7_OSCIN_SEL_VCO; // Register 4 _lmk04816_regs.CLKout8_9_DIV = master_clock_div; @@ -786,39 +860,55 @@ private: static_cast<uint16_t>(std::ceil(_vco_freq / _system_ref_rate)); // Register 6 - _lmk04816_regs.CLKout0_TYPE = lmk04816_regs_t::CLKOUT0_TYPE_LVDS; //FPGA - _lmk04816_regs.CLKout1_TYPE = lmk04816_regs_t::CLKOUT1_TYPE_P_DOWN; //CPRI feedback clock, use LVDS - _lmk04816_regs.CLKout2_TYPE = lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP; //DB_0_RX - _lmk04816_regs.CLKout3_TYPE = lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP; //DB_1_RX + _lmk04816_regs.CLKout0_TYPE = lmk04816_regs_t::CLKOUT0_TYPE_LVDS; // FPGA + _lmk04816_regs.CLKout1_TYPE = + lmk04816_regs_t::CLKOUT1_TYPE_P_DOWN; // CPRI feedback clock, use LVDS + _lmk04816_regs.CLKout2_TYPE = + lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP; // DB_0_RX + _lmk04816_regs.CLKout3_TYPE = + lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP; // DB_1_RX // Register 7 - _lmk04816_regs.CLKout4_TYPE = lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP; //DB_1_TX - _lmk04816_regs.CLKout5_TYPE = lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP; //DB_0_TX - _lmk04816_regs.CLKout6_TYPE = lmk04816_regs_t::CLKOUT6_TYPE_LVPECL_700MVPP; //DB0_DAC - _lmk04816_regs.CLKout7_TYPE = lmk04816_regs_t::CLKOUT7_TYPE_LVPECL_700MVPP; //DB1_DAC - _lmk04816_regs.CLKout8_TYPE = lmk04816_regs_t::CLKOUT8_TYPE_LVPECL_700MVPP; //DB0_ADC + _lmk04816_regs.CLKout4_TYPE = + lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP; // DB_1_TX + _lmk04816_regs.CLKout5_TYPE = + lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP; // DB_0_TX + _lmk04816_regs.CLKout6_TYPE = + lmk04816_regs_t::CLKOUT6_TYPE_LVPECL_700MVPP; // DB0_DAC + _lmk04816_regs.CLKout7_TYPE = + lmk04816_regs_t::CLKOUT7_TYPE_LVPECL_700MVPP; // DB1_DAC + _lmk04816_regs.CLKout8_TYPE = + lmk04816_regs_t::CLKOUT8_TYPE_LVPECL_700MVPP; // DB0_ADC // Register 8 - _lmk04816_regs.CLKout9_TYPE = lmk04816_regs_t::CLKOUT9_TYPE_LVPECL_700MVPP; //DB1_ADC - _lmk04816_regs.CLKout10_TYPE = lmk04816_regs_t::CLKOUT10_TYPE_LVDS; //REF_CLKOUT - _lmk04816_regs.CLKout11_TYPE = lmk04816_regs_t::CLKOUT11_TYPE_P_DOWN; //Debug header, use LVPECL + _lmk04816_regs.CLKout9_TYPE = + lmk04816_regs_t::CLKOUT9_TYPE_LVPECL_700MVPP; // DB1_ADC + _lmk04816_regs.CLKout10_TYPE = lmk04816_regs_t::CLKOUT10_TYPE_LVDS; // REF_CLKOUT + _lmk04816_regs.CLKout11_TYPE = + lmk04816_regs_t::CLKOUT11_TYPE_P_DOWN; // Debug header, use LVPECL // Register 10 - _lmk04816_regs.EN_OSCout0 = lmk04816_regs_t::EN_OSCOUT0_DISABLED; //Debug header - _lmk04816_regs.FEEDBACK_MUX = 5; //use output 10 (REF OUT) for feedback + _lmk04816_regs.EN_OSCout0 = lmk04816_regs_t::EN_OSCOUT0_DISABLED; // Debug header + _lmk04816_regs.FEEDBACK_MUX = 5; // use output 10 (REF OUT) for feedback _lmk04816_regs.EN_FEEDBACK_MUX = lmk04816_regs_t::EN_FEEDBACK_MUX_ENABLED; // Register 11 // MODE set in individual cases above _lmk04816_regs.SYNC_QUAL = lmk04816_regs_t::SYNC_QUAL_FB_MUX; - _lmk04816_regs.EN_SYNC = lmk04816_regs_t::EN_SYNC_ENABLE; - _lmk04816_regs.NO_SYNC_CLKout0_1 = lmk04816_regs_t::NO_SYNC_CLKOUT0_1_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout2_3 = lmk04816_regs_t::NO_SYNC_CLKOUT2_3_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout4_5 = lmk04816_regs_t::NO_SYNC_CLKOUT4_5_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout6_7 = lmk04816_regs_t::NO_SYNC_CLKOUT6_7_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout8_9 = lmk04816_regs_t::NO_SYNC_CLKOUT8_9_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout10_11 = lmk04816_regs_t::NO_SYNC_CLKOUT10_11_CLOCK_XY_SYNC; + _lmk04816_regs.EN_SYNC = lmk04816_regs_t::EN_SYNC_ENABLE; + _lmk04816_regs.NO_SYNC_CLKout0_1 = + lmk04816_regs_t::NO_SYNC_CLKOUT0_1_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout2_3 = + lmk04816_regs_t::NO_SYNC_CLKOUT2_3_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout4_5 = + lmk04816_regs_t::NO_SYNC_CLKOUT4_5_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout6_7 = + lmk04816_regs_t::NO_SYNC_CLKOUT6_7_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout8_9 = + lmk04816_regs_t::NO_SYNC_CLKOUT8_9_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout10_11 = + lmk04816_regs_t::NO_SYNC_CLKOUT10_11_CLOCK_XY_SYNC; _lmk04816_regs.SYNC_TYPE = lmk04816_regs_t::SYNC_TYPE_INPUT; // Register 12 @@ -826,14 +916,18 @@ private: /* Input Clock Configurations */ // Register 13 - _lmk04816_regs.EN_CLKin0 = lmk04816_regs_t::EN_CLKIN0_NO_VALID_USE; // This is not connected - _lmk04816_regs.EN_CLKin2 = lmk04816_regs_t::EN_CLKIN2_NO_VALID_USE; // Used only for CPRI + _lmk04816_regs.EN_CLKin0 = + lmk04816_regs_t::EN_CLKIN0_NO_VALID_USE; // This is not connected + _lmk04816_regs.EN_CLKin2 = + lmk04816_regs_t::EN_CLKIN2_NO_VALID_USE; // Used only for CPRI _lmk04816_regs.Status_CLKin1_MUX = lmk04816_regs_t::STATUS_CLKIN1_MUX_UWIRE_RB; _lmk04816_regs.CLKin_Select_MODE = lmk04816_regs_t::CLKIN_SELECT_MODE_CLKIN1_MAN; - _lmk04816_regs.HOLDOVER_MUX = lmk04816_regs_t::HOLDOVER_MUX_PLL1_R; + _lmk04816_regs.HOLDOVER_MUX = lmk04816_regs_t::HOLDOVER_MUX_PLL1_R; // Register 14 - _lmk04816_regs.Status_CLKin1_TYPE = lmk04816_regs_t::STATUS_CLKIN1_TYPE_OUT_PUSH_PULL; - _lmk04816_regs.Status_CLKin0_TYPE = lmk04816_regs_t::STATUS_CLKIN0_TYPE_OUT_PUSH_PULL; + _lmk04816_regs.Status_CLKin1_TYPE = + lmk04816_regs_t::STATUS_CLKIN1_TYPE_OUT_PUSH_PULL; + _lmk04816_regs.Status_CLKin0_TYPE = + lmk04816_regs_t::STATUS_CLKIN0_TYPE_OUT_PUSH_PULL; // Register 26 // PLL2_CP_GAIN_26 set above in individual cases @@ -848,7 +942,8 @@ private: // PLL1_N_28 and PLL2_R_28 are set in the individual cases above // Register 29 - _lmk04816_regs.PLL2_N_CAL_29 = _lmk04816_regs.PLL2_N_30; // N_CAL should always match N + _lmk04816_regs.PLL2_N_CAL_29 = + _lmk04816_regs.PLL2_N_30; // N_CAL should always match N _lmk04816_regs.OSCin_FREQ_29 = lmk04816_regs_t::OSCIN_FREQ_29_63_TO_127MHZ; // Register 30 @@ -861,12 +956,18 @@ private: _delays = X300_REV0_6_CLK_DELAYS; } - //Apply delay values - set_clock_delay(X300_CLOCK_WHICH_FPGA, _delays.fpga_dly_ns, false); - set_clock_delay(X300_CLOCK_WHICH_DB0_RX, _delays.db_rx_dly_ns, false); //Sets both Ch0 and Ch1 - set_clock_delay(X300_CLOCK_WHICH_DB0_TX, _delays.db_tx_dly_ns, false); //Sets both Ch0 and Ch1 - set_clock_delay(X300_CLOCK_WHICH_ADC0, _delays.adc_dly_ns, false); //Sets both Ch0 and Ch1 - set_clock_delay(X300_CLOCK_WHICH_DAC0, _delays.dac_dly_ns, false); //Sets both Ch0 and Ch1 + // Apply delay values + set_clock_delay(X300_CLOCK_WHICH_FPGA, _delays.fpga_dly_ns, false); + set_clock_delay(X300_CLOCK_WHICH_DB0_RX, + _delays.db_rx_dly_ns, + false); // Sets both Ch0 and Ch1 + set_clock_delay(X300_CLOCK_WHICH_DB0_TX, + _delays.db_tx_dly_ns, + false); // Sets both Ch0 and Ch1 + set_clock_delay( + X300_CLOCK_WHICH_ADC0, _delays.adc_dly_ns, false); // Sets both Ch0 and Ch1 + set_clock_delay( + X300_CLOCK_WHICH_DAC0, _delays.dac_dly_ns, false); // Sets both Ch0 and Ch1 /* Write the configuration values into the LMK */ for (uint8_t i = 1; i <= 16; ++i) { @@ -879,24 +980,25 @@ private: this->sync_clocks(); } - const spi_iface::sptr _spiface; - const int _slaveno; - const size_t _hw_rev; + const spi_iface::sptr _spiface; + const int _slaveno; + const size_t _hw_rev; // This is technically constant, but it can be coerced during initialization - double _master_clock_rate; - const double _dboard_clock_rate; - const double _system_ref_rate; - lmk04816_regs_t _lmk04816_regs; - double _vco_freq; - x300_clk_delays _delays; + double _master_clock_rate; + const double _dboard_clock_rate; + const double _system_ref_rate; + lmk04816_regs_t _lmk04816_regs; + double _vco_freq; + x300_clk_delays _delays; }; x300_clock_ctrl::sptr x300_clock_ctrl::make(uhd::spi_iface::sptr spiface, - const size_t slaveno, - const size_t hw_rev, - const double master_clock_rate, - const double dboard_clock_rate, - const double system_ref_rate) { - return sptr(new x300_clock_ctrl_impl(spiface, slaveno, hw_rev, - master_clock_rate, dboard_clock_rate, system_ref_rate)); + const size_t slaveno, + const size_t hw_rev, + const double master_clock_rate, + const double dboard_clock_rate, + const double system_ref_rate) +{ + return sptr(new x300_clock_ctrl_impl( + spiface, slaveno, hw_rev, master_clock_rate, dboard_clock_rate, system_ref_rate)); } diff --git a/host/lib/usrp/x300/x300_clock_ctrl.hpp b/host/lib/usrp/x300/x300_clock_ctrl.hpp index 3ab8b45f9..609464ca0 100644 --- a/host/lib/usrp/x300/x300_clock_ctrl.hpp +++ b/host/lib/usrp/x300/x300_clock_ctrl.hpp @@ -13,8 +13,7 @@ #include <boost/utility.hpp> -enum x300_clock_which_t -{ +enum x300_clock_which_t { X300_CLOCK_WHICH_ADC0, X300_CLOCK_WHICH_ADC1, X300_CLOCK_WHICH_DAC0, @@ -29,17 +28,16 @@ enum x300_clock_which_t class x300_clock_ctrl : boost::noncopyable { public: - typedef boost::shared_ptr<x300_clock_ctrl> sptr; virtual ~x300_clock_ctrl(void) = 0; static sptr make(uhd::spi_iface::sptr spiface, - const size_t slaveno, - const size_t hw_rev, - const double master_clock_rate, - const double dboard_clock_rate, - const double system_ref_rate); + const size_t slaveno, + const size_t hw_rev, + const double master_clock_rate, + const double dboard_clock_rate, + const double system_ref_rate); /*! Get the master clock rate of the device. * \return the clock frequency in Hz @@ -78,7 +76,8 @@ public: * \param enable true=enable, false=disable * \return a list of clock rates in Hz */ - virtual void enable_dboard_clock(const x300_clock_which_t which, const bool enable) = 0; + virtual void enable_dboard_clock( + const x300_clock_which_t which, const bool enable) = 0; /*! Turn the reference output on/off * \param true = on, false = off @@ -92,7 +91,9 @@ public: * \return the actual delay value set * \throw exception when which invalid or delay_ns out of range */ - virtual double set_clock_delay(const x300_clock_which_t which, const double delay_ns, const bool resync = true) = 0; + virtual double set_clock_delay(const x300_clock_which_t which, + const double delay_ns, + const bool resync = true) = 0; /*! Get the clock delay for the given clock divider. * \param which which clock diff --git a/host/lib/usrp/x300/x300_dac_ctrl.cpp b/host/lib/usrp/x300/x300_dac_ctrl.cpp index a9df96002..f951a44a2 100644 --- a/host/lib/usrp/x300/x300_dac_ctrl.cpp +++ b/host/lib/usrp/x300/x300_dac_ctrl.cpp @@ -7,11 +7,11 @@ #include "x300_dac_ctrl.hpp" #include "x300_regs.hpp" -#include <uhdlib/utils/system_time.hpp> +#include <uhd/exception.hpp> #include <uhd/types/time_spec.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/safe_call.hpp> -#include <uhd/exception.hpp> +#include <uhdlib/utils/system_time.hpp> #include <boost/format.hpp> #include <chrono> #include <thread> @@ -22,10 +22,12 @@ using namespace uhd; #define write_ad9146_reg(addr, data) \ _iface->write_spi(_slaveno, spi_config_t::EDGE_RISE, ((addr) << 8) | (data), 16) -#define read_ad9146_reg(addr) \ - (_iface->read_spi(_slaveno, spi_config_t::EDGE_RISE, ((addr) << 8) | (1 << 15), 16) & 0xff) +#define read_ad9146_reg(addr) \ + (_iface->read_spi(_slaveno, spi_config_t::EDGE_RISE, ((addr) << 8) | (1 << 15), 16) \ + & 0xff) -x300_dac_ctrl::~x300_dac_ctrl(void){ +x300_dac_ctrl::~x300_dac_ctrl(void) +{ /* NOP */ } @@ -35,38 +37,41 @@ x300_dac_ctrl::~x300_dac_ctrl(void){ class x300_dac_ctrl_impl : public x300_dac_ctrl { public: - x300_dac_ctrl_impl(uhd::spi_iface::sptr iface, const size_t slaveno, const double refclk): - _iface(iface), _slaveno(static_cast<int>(slaveno)), _refclk(refclk) + x300_dac_ctrl_impl( + uhd::spi_iface::sptr iface, const size_t slaveno, const double refclk) + : _iface(iface), _slaveno(static_cast<int>(slaveno)), _refclk(refclk) { - //Power up all DAC subsystems - write_ad9146_reg(0x01, 0x10); //Up: I DAC, Q DAC, Receiver, Voltage Ref, Clocks - write_ad9146_reg(0x02, 0x00); //No extended delays. Up: Voltage Ref, PLL, DAC, FIFO, Filters + // Power up all DAC subsystems + write_ad9146_reg(0x01, 0x10); // Up: I DAC, Q DAC, Receiver, Voltage Ref, Clocks + write_ad9146_reg( + 0x02, 0x00); // No extended delays. Up: Voltage Ref, PLL, DAC, FIFO, Filters reset(); } ~x300_dac_ctrl_impl(void) { - UHD_SAFE_CALL - ( - //Power down all DAC subsystems - write_ad9146_reg(0x01, 0xEF); //Down: I DAC, Q DAC, Receiver, Voltage Ref, Clocks - write_ad9146_reg(0x02, 0x1F); //No extended delays. Down: Voltage Ref, PLL, DAC, FIFO, Filters + UHD_SAFE_CALL( + // Power down all DAC subsystems + write_ad9146_reg( + 0x01, 0xEF); // Down: I DAC, Q DAC, Receiver, Voltage Ref, Clocks + write_ad9146_reg(0x02, + 0x1F); // No extended delays. Down: Voltage Ref, PLL, DAC, FIFO, Filters ) } void reset() { - //ADI recommendations: + // ADI recommendations: //- soft reset the chip before configuration //- put the chip in sleep mode during configuration and wake it up when done //- configure synchronization settings when sleeping _soft_reset(); _sleep_mode(true); _init(); - //We run backend sync regardless of whether we need to sync multiple DACs - //because we use the internal DAC FIFO to meet system synchronous timing - //and we need to guarantee that the FIFO is not empty. + // We run backend sync regardless of whether we need to sync multiple DACs + // because we use the internal DAC FIFO to meet system synchronous timing + // and we need to guarantee that the FIFO is not empty. _backend_sync(); _sleep_mode(false); } @@ -78,20 +83,20 @@ public: _check_pll(); _check_dac_sync(); return; - } catch (...) {} + } catch (...) { + } std::string err_str; // Try 3 times to sync before giving up - for (size_t retries = 0; retries < 3; retries++) - { + for (size_t retries = 0; retries < 3; retries++) { try { _sleep_mode(true); _init(); _backend_sync(); _sleep_mode(false); return; - } catch (const uhd::runtime_error &e) { + } catch (const uhd::runtime_error& e) { err_str = e.what(); } } @@ -114,23 +119,23 @@ public: // void _init() { - write_ad9146_reg(0x1e, 0x01); //Datasheet: "Set 1 for proper operation" - write_ad9146_reg(0x06, 0xFF); //Clear all event flags + write_ad9146_reg(0x1e, 0x01); // Datasheet: "Set 1 for proper operation" + write_ad9146_reg(0x06, 0xFF); // Clear all event flags // Calculate N0 to be VCO friendly. // Aim for VCO between 1 and 2GHz, assert otherwise. const int N1 = 4; int N0_val, N0; - for (N0_val = 0; N0_val < 3; N0_val++) - { - N0 = (1 << N0_val); //1, 2, 4 - if ((_refclk * N0 * N1) >= 1e9) break; + for (N0_val = 0; N0_val < 3; N0_val++) { + N0 = (1 << N0_val); // 1, 2, 4 + if ((_refclk * N0 * N1) >= 1e9) + break; } UHD_ASSERT_THROW((_refclk * N0 * N1) >= 1e9); UHD_ASSERT_THROW((_refclk * N0 * N1) <= 2e9); // Start PLL - write_ad9146_reg(0x06, 0xC0); //Clear PLL event flags + write_ad9146_reg(0x06, 0xC0); // Clear PLL event flags write_ad9146_reg(0x0C, 0xD1); // Narrow PLL loop filter, Midrange charge pump. write_ad9146_reg(0x0D, 0xD1 | (N0_val << 2)); // N1=4, N2=16, N0 as calculated write_ad9146_reg(0x0A, 0xCF); // Auto init VCO band training as per datasheet @@ -149,7 +154,7 @@ public: // - First transaction goes into low bits // - Second transaction goes into high bits // therefore, we want Q to go first (bit 6 == 1) - write_ad9146_reg(0x03, (1 << 6)); //2s comp, i first, byte mode + write_ad9146_reg(0x03, (1 << 6)); // 2s comp, i first, byte mode // Configure interpolation filters write_ad9146_reg(0x1C, 0x00); // Configure HB1 @@ -165,31 +170,33 @@ public: // void _backend_sync(void) { - write_ad9146_reg(0x10, 0x40); // Disable SYNC mode to reset state machines. + write_ad9146_reg(0x10, 0x40); // Disable SYNC mode to reset state machines. - //SYNC Settings: + // SYNC Settings: //- SYNC = Enabled //- Data Rate Mode: Synchronize at the rate at which data is consumed and not at // the granularity of the FIFO //- Falling edge sync: For the X300, DACCLK is generated using RefClk. Within the // DAC, the RefClk is sampled by DACCLK to sync interpolation // stages across multiple DACs. To ensure that we capture the - // RefClk when it is not transitioning, we sample on the falling - // edge of DACCLK + // RefClk when it is not transitioning, we sample on the + // falling edge of DACCLK //- Averaging = MAX - write_ad9146_reg(0x10, 0xC7); // Enable SYNC mode. Falling edge sync. Averaging set to 128. + write_ad9146_reg( + 0x10, 0xC7); // Enable SYNC mode. Falling edge sync. Averaging set to 128. - //Wait for backend SYNC state machine to lock before proceeding. This guarantees that the - //inputs and output of the FIFO have synchronized clocks + // Wait for backend SYNC state machine to lock before proceeding. This guarantees + // that the inputs and output of the FIFO have synchronized clocks _check_dac_sync(); - //FIFO write pointer offset - //One of ADI's requirements to use data-rate synchronization in PLL mode is to meet - //setup and hold times for RefClk -> DCI clock which we *do not* currently meet in - //the FPGA. The DCI clock reaches a full RefClk cycle later which results in the - //FIFO popping before the first push. This results in a steady-state FIFO fullness - //of pointer - 1. To reach the optimal FIFO fullness of 4 we set the pointer to 5. - //FIXME: At some point we should meet timing on this interface + // FIFO write pointer offset + // One of ADI's requirements to use data-rate synchronization in PLL mode is to + // meet setup and hold times for RefClk -> DCI clock which we *do not* currently + // meet in the FPGA. The DCI clock reaches a full RefClk cycle later which results + // in the FIFO popping before the first push. This results in a steady-state FIFO + // fullness of pointer - 1. To reach the optimal FIFO fullness of 4 we set the + // pointer to 5. + // FIXME: At some point we should meet timing on this interface write_ad9146_reg(0x17, 0x05); // We are requesting a soft FIFO align just to put the FIFO @@ -204,22 +211,23 @@ public: // void _check_pll() { - //Clear PLL event flags + // Clear PLL event flags write_ad9146_reg(0x06, 0xC0); // Verify PLL is Locked. 1 sec timeout. // NOTE: Data sheet inconsistent about which pins give PLL lock status. FIXME! const time_spec_t exit_time = uhd::get_system_time() + time_spec_t(1.0); - while (true) - { + while (true) { const size_t reg_e = read_ad9146_reg(0x0E); // PLL Status (Expect bit 7 = 1) - const size_t reg_6 = read_ad9146_reg(0x06); // Event Flags (Expect bit 7 = 0 and bit 6 = 1) + const size_t reg_6 = + read_ad9146_reg(0x06); // Event Flags (Expect bit 7 = 0 and bit 6 = 1) if ((((reg_e >> 7) & 0x1) == 0x1) && (((reg_6 >> 6) & 0x3) == 0x1)) break; if (exit_time < uhd::get_system_time()) - throw uhd::runtime_error("x300_dac_ctrl: timeout waiting for DAC PLL to lock"); - if (reg_6 & (1 << 7)) // Lock lost? - write_ad9146_reg(0x06, 0xC0); // Clear PLL event flags + throw uhd::runtime_error( + "x300_dac_ctrl: timeout waiting for DAC PLL to lock"); + if (reg_6 & (1 << 7)) // Lock lost? + write_ad9146_reg(0x06, 0xC0); // Clear PLL event flags std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } @@ -234,21 +242,25 @@ public: write_ad9146_reg(0x12, 0x00); const time_spec_t exit_time = uhd::get_system_time() + time_spec_t(1.0); - while (true) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // wait for sync to complete - const size_t reg_12 = read_ad9146_reg(0x12); // Sync Status (Expect bit 7 = 0, bit 6 = 1) - const size_t reg_6 = read_ad9146_reg(0x06); // Event Flags (Expect bit 5 = 0 and bit 4 = 1) + while (true) { + std::this_thread::sleep_for( + std::chrono::milliseconds(1)); // wait for sync to complete + const size_t reg_12 = + read_ad9146_reg(0x12); // Sync Status (Expect bit 7 = 0, bit 6 = 1) + const size_t reg_6 = + read_ad9146_reg(0x06); // Event Flags (Expect bit 5 = 0 and bit 4 = 1) if ((((reg_12 >> 6) & 0x3) == 0x1) && (((reg_6 >> 4) & 0x3) == 0x1)) break; if (exit_time < uhd::get_system_time()) - throw uhd::runtime_error("x300_dac_ctrl: timeout waiting for backend synchronization"); + throw uhd::runtime_error( + "x300_dac_ctrl: timeout waiting for backend synchronization"); if (reg_6 & (1 << 5)) - write_ad9146_reg(0x06, 0x30); // Clear Sync event flags + write_ad9146_reg(0x06, 0x30); // Clear Sync event flags #ifdef X300_DAC_RETRY_BACKEND_SYNC - if (reg_12 & (1 << 7)) { // Sync acquired and lost? - write_ad9146_reg(0x10, 0xC7); // Enable SYNC mode. Falling edge sync. Averaging set to 128. - write_ad9146_reg(0x12, 0x00); // Clear Sync event flags + if (reg_12 & (1 << 7)) { // Sync acquired and lost? + write_ad9146_reg(0x10, + 0xC7); // Enable SYNC mode. Falling edge sync. Averaging set to 128. + write_ad9146_reg(0x12, 0x00); // Clear Sync event flags } #endif } @@ -262,7 +274,11 @@ public: // Register 0x19 has a thermometer indicator of the FIFO depth const size_t reg_19 = read_ad9146_reg(0x19); if ((reg_19 & 0xFF) != 0xF) { - std::string msg((boost::format("x300_dac_ctrl: front-end sync failed. unexpected FIFO depth [0x%x]") % (reg_19 & 0xFF)).str()); + std::string msg( + (boost::format( + "x300_dac_ctrl: front-end sync failed. unexpected FIFO depth [0x%x]") + % (reg_19 & 0xFF)) + .str()); if (failure_is_fatal) { throw uhd::runtime_error(msg); } else { @@ -273,10 +289,10 @@ public: void _sleep_mode(bool sleep) { - uint8_t sleep_val = sleep ? (1<<7) : 0x00; - //Set sleep word and default fullscale value - write_ad9146_reg(0x41, sleep_val | 0x01); //I DAC - write_ad9146_reg(0x45, sleep_val | 0x01); //Q DAC + uint8_t sleep_val = sleep ? (1 << 7) : 0x00; + // Set sleep word and default fullscale value + write_ad9146_reg(0x41, sleep_val | 0x01); // I DAC + write_ad9146_reg(0x45, sleep_val | 0x01); // Q DAC } void _soft_reset() @@ -294,7 +310,8 @@ private: /*********************************************************************** * Public make function for the DAC control **********************************************************************/ -x300_dac_ctrl::sptr x300_dac_ctrl::make(uhd::spi_iface::sptr iface, const size_t slaveno, const double clock_rate) +x300_dac_ctrl::sptr x300_dac_ctrl::make( + uhd::spi_iface::sptr iface, const size_t slaveno, const double clock_rate) { return sptr(new x300_dac_ctrl_impl(iface, slaveno, clock_rate)); } diff --git a/host/lib/usrp/x300/x300_dac_ctrl.hpp b/host/lib/usrp/x300/x300_dac_ctrl.hpp index 0ef99011b..74dba0cb4 100644 --- a/host/lib/usrp/x300/x300_dac_ctrl.hpp +++ b/host/lib/usrp/x300/x300_dac_ctrl.hpp @@ -25,7 +25,8 @@ public: * \param spiface the interface to spi * \return a new codec control object */ - static sptr make(uhd::spi_iface::sptr iface, const size_t slaveno, const double clock_rate); + static sptr make( + uhd::spi_iface::sptr iface, const size_t slaveno, const double clock_rate); // ! Reset the DAC virtual void reset(void) = 0; diff --git a/host/lib/usrp/x300/x300_dboard_iface.cpp b/host/lib/usrp/x300/x300_dboard_iface.cpp index 6986ee8ab..36e430985 100644 --- a/host/lib/usrp/x300/x300_dboard_iface.cpp +++ b/host/lib/usrp/x300/x300_dboard_iface.cpp @@ -18,14 +18,13 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -x300_dboard_iface::x300_dboard_iface(const x300_dboard_iface_config_t &config): - _config(config) +x300_dboard_iface::x300_dboard_iface(const x300_dboard_iface_config_t& config) + : _config(config) { - //reset the aux dacs + // reset the aux dacs _dac_regs[UNIT_RX] = ad5623_regs_t(); _dac_regs[UNIT_TX] = ad5623_regs_t(); - for(unit_t unit: _dac_regs.keys()) - { + for (unit_t unit : _dac_regs.keys()) { _dac_regs[unit].data = 1; _dac_regs[unit].addr = ad5623_regs_t::ADDR_ALL; _dac_regs[unit].cmd = ad5623_regs_t::CMD_RESET; @@ -41,11 +40,8 @@ x300_dboard_iface::x300_dboard_iface(const x300_dboard_iface_config_t &config): x300_dboard_iface::~x300_dboard_iface(void) { - UHD_SAFE_CALL - ( - this->set_clock_enabled(UNIT_RX, false); - this->set_clock_enabled(UNIT_TX, false); - ) + UHD_SAFE_CALL(this->set_clock_enabled(UNIT_RX, false); + this->set_clock_enabled(UNIT_TX, false);) } /*********************************************************************** @@ -53,14 +49,14 @@ x300_dboard_iface::~x300_dboard_iface(void) **********************************************************************/ void x300_dboard_iface::set_clock_rate(unit_t unit, double rate) { - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); // Just return if the requested rate is already set if (std::abs(_clock_rates[unit] - rate) < std::numeric_limits<double>::epsilon()) return; - switch(unit) - { + switch (unit) { case UNIT_RX: _config.clock->set_dboard_rate(_config.which_rx_clk, rate); break; @@ -70,20 +66,21 @@ void x300_dboard_iface::set_clock_rate(unit_t unit, double rate) default: UHD_THROW_INVALID_CODE_PATH(); } - _clock_rates[unit] = rate; //set to shadow + _clock_rates[unit] = rate; // set to shadow } double x300_dboard_iface::get_clock_rate(unit_t unit) { - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - return _clock_rates[unit]; //get from shadow + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + return _clock_rates[unit]; // get from shadow } std::vector<double> x300_dboard_iface::get_clock_rates(unit_t unit) { - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - switch(unit) - { + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + switch (unit) { case UNIT_RX: return _config.clock->get_dboard_rates(_config.which_rx_clk); case UNIT_TX: @@ -95,9 +92,9 @@ std::vector<double> x300_dboard_iface::get_clock_rates(unit_t unit) void x300_dboard_iface::set_clock_enabled(unit_t unit, bool enb) { - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); - switch(unit) - { + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); + switch (unit) { case UNIT_RX: return _config.clock->enable_dboard_clock(_config.which_rx_clk, enb); case UNIT_TX: @@ -109,7 +106,8 @@ void x300_dboard_iface::set_clock_enabled(unit_t unit, bool enb) double x300_dboard_iface::get_codec_rate(unit_t unit) { - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); return _config.clock->get_master_clock_rate(); } @@ -126,7 +124,8 @@ uint32_t x300_dboard_iface::get_pin_ctrl(unit_t unit) return _config.gpio->get_pin_ctrl(unit); } -void x300_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask) +void x300_dboard_iface::set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask) { _config.gpio->set_atr_reg(unit, reg, value, mask); } @@ -165,34 +164,33 @@ uint32_t x300_dboard_iface::read_gpio(unit_t unit) * SPI **********************************************************************/ void x300_dboard_iface::write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ uint32_t slave = 0; - if (unit == UNIT_TX) slave |= _config.tx_spi_slaveno; - if (unit == UNIT_RX) slave |= _config.rx_spi_slaveno; + if (unit == UNIT_TX) + slave |= _config.tx_spi_slaveno; + if (unit == UNIT_RX) + slave |= _config.rx_spi_slaveno; _config.spi->write_spi(int(slave), config, data, num_bits); } uint32_t x300_dboard_iface::read_write_spi( - unit_t unit, - const spi_config_t &config, - uint32_t data, - size_t num_bits -){ - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + unit_t unit, const spi_config_t& config, uint32_t data, size_t num_bits) +{ + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); return _config.spi->read_spi( - (unit==dboard_iface::UNIT_TX)?_config.tx_spi_slaveno:_config.rx_spi_slaveno, - config, data, num_bits); + (unit == dboard_iface::UNIT_TX) ? _config.tx_spi_slaveno : _config.rx_spi_slaveno, + config, + data, + num_bits); } /*********************************************************************** * I2C **********************************************************************/ -void x300_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t &bytes) +void x300_dboard_iface::write_i2c(uint16_t addr, const byte_vector_t& bytes) { return _config.i2c->write_i2c(addr, bytes); } @@ -207,76 +205,67 @@ byte_vector_t x300_dboard_iface::read_i2c(uint16_t addr, size_t num_bytes) **********************************************************************/ void x300_dboard_iface::_write_aux_dac(unit_t unit) { - static const uhd::dict<unit_t, int> unit_to_spi_dac = map_list_of - (UNIT_RX, DB_RX_LSDAC_SEN) - (UNIT_TX, DB_TX_LSDAC_SEN) - ; - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + static const uhd::dict<unit_t, int> unit_to_spi_dac = + map_list_of(UNIT_RX, DB_RX_LSDAC_SEN)(UNIT_TX, DB_TX_LSDAC_SEN); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); _config.spi->write_spi( - unit_to_spi_dac[unit], spi_config_t::EDGE_FALL, - _dac_regs[unit].get_reg(), 24 - ); + unit_to_spi_dac[unit], spi_config_t::EDGE_FALL, _dac_regs[unit].get_reg(), 24); } void x300_dboard_iface::write_aux_dac(unit_t unit, aux_dac_t which, double value) { - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); - _dac_regs[unit].data = boost::math::iround(4095*value/3.3); - _dac_regs[unit].cmd = ad5623_regs_t::CMD_WR_UP_DAC_CHAN_N; + _dac_regs[unit].data = boost::math::iround(4095 * value / 3.3); + _dac_regs[unit].cmd = ad5623_regs_t::CMD_WR_UP_DAC_CHAN_N; typedef uhd::dict<aux_dac_t, ad5623_regs_t::addr_t> aux_dac_to_addr; - static const uhd::dict<unit_t, aux_dac_to_addr> unit_to_which_to_addr = map_list_of - (UNIT_RX, map_list_of - (AUX_DAC_A, ad5623_regs_t::ADDR_DAC_A) - (AUX_DAC_B, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_C, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_D, ad5623_regs_t::ADDR_DAC_A) - ) - (UNIT_TX, map_list_of - (AUX_DAC_A, ad5623_regs_t::ADDR_DAC_A) - (AUX_DAC_B, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_C, ad5623_regs_t::ADDR_DAC_B) - (AUX_DAC_D, ad5623_regs_t::ADDR_DAC_A) - ) - ; + static const uhd::dict<unit_t, aux_dac_to_addr> unit_to_which_to_addr = + map_list_of(UNIT_RX, + map_list_of(AUX_DAC_A, ad5623_regs_t::ADDR_DAC_A)(AUX_DAC_B, + ad5623_regs_t::ADDR_DAC_B)(AUX_DAC_C, ad5623_regs_t::ADDR_DAC_B)( + AUX_DAC_D, ad5623_regs_t::ADDR_DAC_A))(UNIT_TX, + map_list_of(AUX_DAC_A, ad5623_regs_t::ADDR_DAC_A)(AUX_DAC_B, + ad5623_regs_t::ADDR_DAC_B)(AUX_DAC_C, ad5623_regs_t::ADDR_DAC_B)( + AUX_DAC_D, ad5623_regs_t::ADDR_DAC_A)); _dac_regs[unit].addr = unit_to_which_to_addr[unit][which]; this->_write_aux_dac(unit); } double x300_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which) { - static const uhd::dict<unit_t, int> unit_to_spi_adc = map_list_of - (UNIT_RX, DB_RX_LSADC_SEN) - (UNIT_TX, DB_TX_LSADC_SEN) - ; + static const uhd::dict<unit_t, int> unit_to_spi_adc = + map_list_of(UNIT_RX, DB_RX_LSADC_SEN)(UNIT_TX, DB_TX_LSADC_SEN); - if (unit == UNIT_BOTH) throw uhd::runtime_error("UNIT_BOTH not supported."); + if (unit == UNIT_BOTH) + throw uhd::runtime_error("UNIT_BOTH not supported."); - //setup spi config args + // setup spi config args spi_config_t config; config.mosi_edge = spi_config_t::EDGE_FALL; config.miso_edge = spi_config_t::EDGE_RISE; - //setup the spi registers + // setup the spi registers ad7922_regs_t ad7922_regs; - switch(which){ - case AUX_ADC_A: ad7922_regs.mod = 0; break; - case AUX_ADC_B: ad7922_regs.mod = 1; break; - } ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn + switch (which) { + case AUX_ADC_A: + ad7922_regs.mod = 0; + break; + case AUX_ADC_B: + ad7922_regs.mod = 1; + break; + } + ad7922_regs.chn = ad7922_regs.mod; // normal mode: mod == chn - //write and read spi - _config.spi->write_spi( - unit_to_spi_adc[unit], config, - ad7922_regs.get_reg(), 16 - ); - ad7922_regs.set_reg(uint16_t(_config.spi->read_spi( - unit_to_spi_adc[unit], config, - ad7922_regs.get_reg(), 16 - ))); - - //convert to voltage and return - return 3.3*ad7922_regs.result/4095; + // write and read spi + _config.spi->write_spi(unit_to_spi_adc[unit], config, ad7922_regs.get_reg(), 16); + ad7922_regs.set_reg(uint16_t( + _config.spi->read_spi(unit_to_spi_adc[unit], config, ad7922_regs.get_reg(), 16))); + + // convert to voltage and return + return 3.3 * ad7922_regs.result / 4095; } uhd::time_spec_t x300_dboard_iface::get_command_time() @@ -290,15 +279,13 @@ void x300_dboard_iface::set_command_time(const uhd::time_spec_t& t) } void x300_dboard_iface::add_rx_fe( - const std::string& fe_name, - rx_frontend_core_3000::sptr fe_core) + const std::string& fe_name, rx_frontend_core_3000::sptr fe_core) { _rx_fes[fe_name] = fe_core; } void x300_dboard_iface::set_fe_connection( - unit_t unit, const std::string& fe_name, - const fe_connection_t& fe_conn) + unit_t unit, const std::string& fe_name, const fe_connection_t& fe_conn) { if (unit == UNIT_RX) { if (_rx_fes.has_key(fe_name)) { diff --git a/host/lib/usrp/x300/x300_dboard_iface.hpp b/host/lib/usrp/x300/x300_dboard_iface.hpp index f41bb3d42..713c90748 100644 --- a/host/lib/usrp/x300/x300_dboard_iface.hpp +++ b/host/lib/usrp/x300/x300_dboard_iface.hpp @@ -8,41 +8,41 @@ #ifndef INCLUDED_X300_DBOARD_IFACE_HPP #define INCLUDED_X300_DBOARD_IFACE_HPP +#include "ad5623_regs.hpp" //aux dac +#include "ad7922_regs.hpp" //aux adc #include "x300_clock_ctrl.hpp" -#include <uhdlib/usrp/cores/spi_core_3000.hpp> -#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/usrp/dboard_iface.hpp> #include <uhdlib/usrp/cores/gpio_atr_3000.hpp> +#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp> #include <uhdlib/usrp/cores/rx_frontend_core_3000.hpp> -#include "ad7922_regs.hpp" //aux adc -#include "ad5623_regs.hpp" //aux dac -#include <uhd/usrp/dboard_iface.hpp> -#include <uhd/types/dict.hpp> +#include <uhdlib/usrp/cores/spi_core_3000.hpp> struct x300_dboard_iface_config_t { uhd::usrp::gpio_atr::db_gpio_atr_3000::sptr gpio; - spi_core_3000::sptr spi; - size_t rx_spi_slaveno; - size_t tx_spi_slaveno; - uhd::i2c_iface::sptr i2c; - x300_clock_ctrl::sptr clock; - x300_clock_which_t which_rx_clk; - x300_clock_which_t which_tx_clk; - uint8_t dboard_slot; - uhd::timed_wb_iface::sptr cmd_time_ctrl; + spi_core_3000::sptr spi; + size_t rx_spi_slaveno; + size_t tx_spi_slaveno; + uhd::i2c_iface::sptr i2c; + x300_clock_ctrl::sptr clock; + x300_clock_which_t which_rx_clk; + x300_clock_which_t which_tx_clk; + uint8_t dboard_slot; + uhd::timed_wb_iface::sptr cmd_time_ctrl; }; class x300_dboard_iface : public uhd::usrp::dboard_iface { public: - x300_dboard_iface(const x300_dboard_iface_config_t &config); + x300_dboard_iface(const x300_dboard_iface_config_t& config); ~x300_dboard_iface(void); inline special_props_t get_special_props(void) { special_props_t props; props.soft_clock_divider = false; - props.mangle_i2c_addrs = (_config.dboard_slot == 1); + props.mangle_i2c_addrs = (_config.dboard_slot == 1); return props; } @@ -51,7 +51,8 @@ public: void set_pin_ctrl(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_pin_ctrl(unit_t unit); - void set_atr_reg(unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); + void set_atr_reg( + unit_t unit, atr_reg_t reg, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_atr_reg(unit_t unit, atr_reg_t reg); void set_gpio_ddr(unit_t unit, uint32_t value, uint32_t mask = 0xffffffff); uint32_t get_gpio_ddr(unit_t unit); @@ -62,7 +63,7 @@ public: void set_command_time(const uhd::time_spec_t& t); uhd::time_spec_t get_command_time(void); - void write_i2c(uint16_t, const uhd::byte_vector_t &); + void write_i2c(uint16_t, const uhd::byte_vector_t&); uhd::byte_vector_t read_i2c(uint16_t, size_t); void set_clock_rate(unit_t, double); @@ -72,21 +73,12 @@ public: double get_codec_rate(unit_t); void write_spi( - unit_t unit, - const uhd::spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const uhd::spi_config_t& config, uint32_t data, size_t num_bits); uint32_t read_write_spi( - unit_t unit, - const uhd::spi_config_t &config, - uint32_t data, - size_t num_bits - ); + unit_t unit, const uhd::spi_config_t& config, uint32_t data, size_t num_bits); void set_fe_connection( - unit_t unit, const std::string& name, - const uhd::usrp::fe_connection_t& fe_conn); + unit_t unit, const std::string& name, const uhd::usrp::fe_connection_t& fe_conn); // X300 can set the FE connection on the RX side bool has_set_fe_connection(const unit_t unit) override @@ -94,9 +86,7 @@ public: return unit == UNIT_RX; } - void add_rx_fe( - const std::string& fe_name, - rx_frontend_core_3000::sptr fe_core); + void add_rx_fe(const std::string& fe_name, rx_frontend_core_3000::sptr fe_core); private: const x300_dboard_iface_config_t _config; @@ -107,5 +97,4 @@ private: }; - #endif /* INCLUDED_X300_DBOARD_IFACE_HPP */ diff --git a/host/lib/usrp/x300/x300_defaults.hpp b/host/lib/usrp/x300/x300_defaults.hpp index aa8d1b688..2e242f24f 100644 --- a/host/lib/usrp/x300/x300_defaults.hpp +++ b/host/lib/usrp/x300/x300_defaults.hpp @@ -7,103 +7,100 @@ #ifndef INCLUDED_X300_DEFAULTS_HPP #define INCLUDED_X300_DEFAULTS_HPP -#include <uhd/transport/udp_simple.hpp> //mtu #include "../device3/device3_impl.hpp" +#include <uhd/transport/udp_simple.hpp> //mtu #include <string> - -namespace uhd { -namespace usrp { -namespace x300 { +namespace uhd { namespace usrp { namespace x300 { static constexpr size_t NIUSRPRIO_DEFAULT_RPC_PORT = 5444; static constexpr uint32_t RADIO_DEST_PREFIX_TX = 0; -static constexpr size_t XB_DST_E0 = 0; -static constexpr size_t XB_DST_E1 = 1; -static constexpr size_t XB_DST_PCI = 2; -static constexpr size_t XB_DST_R0 = 3; // Radio 0 -> Slot A -static constexpr size_t XB_DST_R1 = 4; // Radio 1 -> Slot B -static constexpr size_t XB_DST_CE0 = 5; +static constexpr size_t XB_DST_E0 = 0; +static constexpr size_t XB_DST_E1 = 1; +static constexpr size_t XB_DST_PCI = 2; +static constexpr size_t XB_DST_R0 = 3; // Radio 0 -> Slot A +static constexpr size_t XB_DST_R1 = 4; // Radio 1 -> Slot B +static constexpr size_t XB_DST_CE0 = 5; -static constexpr size_t SRC_ADDR0 = 0; -static constexpr size_t SRC_ADDR1 = 1; -static constexpr size_t DST_ADDR = 2; +static constexpr size_t SRC_ADDR0 = 0; +static constexpr size_t SRC_ADDR1 = 1; +static constexpr size_t DST_ADDR = 2; -static constexpr double DEFAULT_TICK_RATE = 200e6; // Hz -static constexpr double MAX_TICK_RATE = 200e6; // Hz -static constexpr double MIN_TICK_RATE = 184.32e6; // Hz -static constexpr double BUS_CLOCK_RATE = 187.5e6; // Hz +static constexpr double DEFAULT_TICK_RATE = 200e6; // Hz +static constexpr double MAX_TICK_RATE = 200e6; // Hz +static constexpr double MIN_TICK_RATE = 184.32e6; // Hz +static constexpr double BUS_CLOCK_RATE = 187.5e6; // Hz -static const std::string FW_FILE_NAME = "usrp_x300_fw.bin"; +static const std::string FW_FILE_NAME = "usrp_x300_fw.bin"; // Clock & Time-related defaults static const std::string DEFAULT_CLOCK_SOURCE = "internal"; static const std::string DEFAULT_TIME_SOURCE = "internal"; -static const bool DEFAULT_TIME_OUTPUT = true; +static const bool DEFAULT_TIME_OUTPUT = true; static const std::vector<std::string> CLOCK_SOURCE_OPTIONS{ - "internal", - "external", - "gpsdo" -}; + "internal", "external", "gpsdo"}; static const std::vector<std::string> TIME_SOURCE_OPTIONS{ - "internal", - "external", - "gpsdo" -}; + "internal", "external", "gpsdo"}; static const std::vector<double> EXTERNAL_FREQ_OPTIONS{10e6, 30.72e6, 200e6}; -static constexpr size_t RX_SW_BUFF_SIZE_ETH = 0x2000000;//32MiB For an ~8k frame size any size >32MiB is just wasted buffer space -static constexpr size_t RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib - -//The FIFO closest to the DMA controller is 1023 elements deep for RX and 1029 elements deep for TX -//where an element is 8 bytes. The buffers (number of frames * frame size) must be aligned to the -//memory page size. For the control, we are getting lucky because 64 frames * 256 bytes each aligns -//with the typical page size of 4096 bytes. Since most page sizes are 4096 bytes or some multiple of -//that, keep the number of frames * frame size aligned to it. -static constexpr size_t PCIE_RX_DATA_FRAME_SIZE = 4096; //bytes -static constexpr size_t PCIE_RX_DATA_NUM_FRAMES = 4096; -static constexpr size_t PCIE_TX_DATA_FRAME_SIZE = 4096; //bytes -static constexpr size_t PCIE_TX_DATA_NUM_FRAMES = 4096; -static constexpr size_t PCIE_MSG_FRAME_SIZE = 256; //bytes -static constexpr size_t PCIE_MSG_NUM_FRAMES = 64; -static constexpr size_t PCIE_MAX_CHANNELS = 6; -static constexpr size_t PCIE_MAX_MUXED_CTRL_XPORTS = 32; -static constexpr size_t PCIE_MAX_MUXED_ASYNC_XPORTS = 4; - -static const size_t DATA_FRAME_MAX_SIZE = 8000; // CHDR packet size in bytes -static const size_t XGE_DATA_FRAME_SEND_SIZE = 4000; // Reduced to make sure flow control packets are not blocked for too long at high rates -static const size_t XGE_DATA_FRAME_RECV_SIZE = 8000; -static const size_t GE_DATA_FRAME_SEND_SIZE = 1472; -static const size_t GE_DATA_FRAME_RECV_SIZE = 1472; - -static const size_t ETH_MSG_FRAME_SIZE = uhd::transport::udp_simple::mtu; //bytes +static constexpr size_t RX_SW_BUFF_SIZE_ETH = + 0x2000000; // 32MiB For an ~8k frame size any size >32MiB is just wasted buffer + // space +static constexpr size_t RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; // 1Mib + +// The FIFO closest to the DMA controller is 1023 elements deep for RX and 1029 elements +// deep for TX where an element is 8 bytes. The buffers (number of frames * frame size) +// must be aligned to the memory page size. For the control, we are getting lucky because +// 64 frames * 256 bytes each aligns with the typical page size of 4096 bytes. Since most +// page sizes are 4096 bytes or some multiple of that, keep the number of frames * frame +// size aligned to it. +static constexpr size_t PCIE_RX_DATA_FRAME_SIZE = 4096; // bytes +static constexpr size_t PCIE_RX_DATA_NUM_FRAMES = 4096; +static constexpr size_t PCIE_TX_DATA_FRAME_SIZE = 4096; // bytes +static constexpr size_t PCIE_TX_DATA_NUM_FRAMES = 4096; +static constexpr size_t PCIE_MSG_FRAME_SIZE = 256; // bytes +static constexpr size_t PCIE_MSG_NUM_FRAMES = 64; +static constexpr size_t PCIE_MAX_CHANNELS = 6; +static constexpr size_t PCIE_MAX_MUXED_CTRL_XPORTS = 32; +static constexpr size_t PCIE_MAX_MUXED_ASYNC_XPORTS = 4; + +static const size_t DATA_FRAME_MAX_SIZE = 8000; // CHDR packet size in bytes +static const size_t XGE_DATA_FRAME_SEND_SIZE = + 4000; // Reduced to make sure flow control packets are not blocked for too long at + // high rates +static const size_t XGE_DATA_FRAME_RECV_SIZE = 8000; +static const size_t GE_DATA_FRAME_SEND_SIZE = 1472; +static const size_t GE_DATA_FRAME_RECV_SIZE = 1472; + +static const size_t ETH_MSG_FRAME_SIZE = uhd::transport::udp_simple::mtu; // bytes // MTU throttling for ethernet/TX (see above): static constexpr size_t ETH_DATA_FRAME_MAX_TX_SIZE = 8000; -static constexpr double RECV_OFFLOAD_BUFFER_TIMEOUT = 0.1; //seconds -static constexpr double THREAD_BUFFER_TIMEOUT = 0.1; // Time in seconds +static constexpr double RECV_OFFLOAD_BUFFER_TIMEOUT = 0.1; // seconds +static constexpr double THREAD_BUFFER_TIMEOUT = 0.1; // Time in seconds -static constexpr size_t ETH_MSG_NUM_FRAMES = 64; -static constexpr size_t ETH_DATA_NUM_FRAMES = 32; -static constexpr double DEFAULT_SYSREF_RATE = 10e6; +static constexpr size_t ETH_MSG_NUM_FRAMES = 64; +static constexpr size_t ETH_DATA_NUM_FRAMES = 32; +static constexpr double DEFAULT_SYSREF_RATE = 10e6; // Limit the number of initialization threads -static const size_t MAX_INIT_THREADS = 10; - -static const size_t MAX_RATE_PCIE = 800000000; // bytes/s -static const size_t MAX_RATE_10GIGE = (size_t)( // bytes/s - 10e9 / 8 * // wire speed multiplied by percentage of packets that is sample data - ( float(DATA_FRAME_MAX_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) / - float(DATA_FRAME_MAX_SIZE + 8 /* UDP header */ + 20 /* Ethernet header length */ ))); -static const size_t MAX_RATE_1GIGE = (size_t)( // bytes/s - 10e9 / 8 * // wire speed multiplied by percentage of packets that is sample data - ( float(GE_DATA_FRAME_RECV_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) / - float(GE_DATA_FRAME_RECV_SIZE + 8 /* UDP header */ + 20 /* Ethernet header length */ ))); +static const size_t MAX_INIT_THREADS = 10; + +static const size_t MAX_RATE_PCIE = 800000000; // bytes/s +static const size_t MAX_RATE_10GIGE = (size_t)( // bytes/s + 10e9 / 8 * // wire speed multiplied by percentage of packets that is sample data + (float(DATA_FRAME_MAX_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) + / float(DATA_FRAME_MAX_SIZE + + 8 /* UDP header */ + 20 /* Ethernet header length */))); +static const size_t MAX_RATE_1GIGE = (size_t)( // bytes/s + 10e9 / 8 * // wire speed multiplied by percentage of packets that is sample data + (float(GE_DATA_FRAME_RECV_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) + / float(GE_DATA_FRAME_RECV_SIZE + + 8 /* UDP header */ + 20 /* Ethernet header length */))); }}} /* namespace uhd::usrp::x300 */ #endif /* INCLUDED_X300_DEFAULTS_HPP */ - diff --git a/host/lib/usrp/x300/x300_device_args.hpp b/host/lib/usrp/x300/x300_device_args.hpp index db1a01212..bdb3762af 100644 --- a/host/lib/usrp/x300/x300_device_args.hpp +++ b/host/lib/usrp/x300/x300_device_args.hpp @@ -7,8 +7,8 @@ #ifndef INCLUDED_X300_DEV_ARGS_HPP #define INCLUDED_X300_DEV_ARGS_HPP -#include "x300_impl.hpp" #include "x300_defaults.hpp" +#include "x300_impl.hpp" #include <uhdlib/usrp/constrained_device_args.hpp> namespace uhd { namespace usrp { namespace x300 { @@ -16,97 +16,116 @@ namespace uhd { namespace usrp { namespace x300 { class x300_device_args_t : public constrained_device_args_t { public: - x300_device_args_t(): - _master_clock_rate("master_clock_rate", DEFAULT_TICK_RATE), - _dboard_clock_rate("dboard_clock_rate", -1), - _system_ref_rate("system_ref_rate", DEFAULT_SYSREF_RATE), - _clock_source("clock_source", DEFAULT_CLOCK_SOURCE), - _time_source("time_source", DEFAULT_TIME_SOURCE), - _first_addr("addr", ""), - _second_addr("second_addr", ""), - _resource("resource", ""), - _self_cal_adc_delay("self_cal_adc_delay", false), - _ext_adc_self_test("ext_adc_self_test", false), - _ext_adc_self_test_duration("ext_adc_self_test", 30.0), - _recover_mb_eeprom("recover_mb_eeprom", false), - _ignore_cal_file("ignore_cal_file", false), - _niusrprio_rpc_port("niusrprio_rpc_port", NIUSRPRIO_DEFAULT_RPC_PORT), - _has_fw_file("fw", false), - _fw_file("fw", ""), - _blank_eeprom("blank_eeprom", false), - _enable_tx_dual_eth("enable_tx_dual_eth", false) + x300_device_args_t() + : _master_clock_rate("master_clock_rate", DEFAULT_TICK_RATE) + , _dboard_clock_rate("dboard_clock_rate", -1) + , _system_ref_rate("system_ref_rate", DEFAULT_SYSREF_RATE) + , _clock_source("clock_source", DEFAULT_CLOCK_SOURCE) + , _time_source("time_source", DEFAULT_TIME_SOURCE) + , _first_addr("addr", "") + , _second_addr("second_addr", "") + , _resource("resource", "") + , _self_cal_adc_delay("self_cal_adc_delay", false) + , _ext_adc_self_test("ext_adc_self_test", false) + , _ext_adc_self_test_duration("ext_adc_self_test", 30.0) + , _recover_mb_eeprom("recover_mb_eeprom", false) + , _ignore_cal_file("ignore_cal_file", false) + , _niusrprio_rpc_port("niusrprio_rpc_port", NIUSRPRIO_DEFAULT_RPC_PORT) + , _has_fw_file("fw", false) + , _fw_file("fw", "") + , _blank_eeprom("blank_eeprom", false) + , _enable_tx_dual_eth("enable_tx_dual_eth", false) { // nop } - double get_master_clock_rate() const { + double get_master_clock_rate() const + { return _master_clock_rate.get(); } - double get_dboard_clock_rate() const { + double get_dboard_clock_rate() const + { return _dboard_clock_rate.get(); } - double get_system_ref_rate() const { + double get_system_ref_rate() const + { return _system_ref_rate.get(); } - std::string get_clock_source() const { + std::string get_clock_source() const + { return _clock_source.get(); } - std::string get_time_source() const { + std::string get_time_source() const + { return _time_source.get(); } - std::string get_first_addr() const { + std::string get_first_addr() const + { return _first_addr.get(); } - std::string get_second_addr() const { + std::string get_second_addr() const + { return _second_addr.get(); } - bool get_self_cal_adc_delay() const { + bool get_self_cal_adc_delay() const + { return _self_cal_adc_delay.get(); } - bool get_ext_adc_self_test() const { + bool get_ext_adc_self_test() const + { return _ext_adc_self_test.get(); } - double get_ext_adc_self_test_duration() const { + double get_ext_adc_self_test_duration() const + { return _ext_adc_self_test_duration.get(); } - bool get_recover_mb_eeprom() const { + bool get_recover_mb_eeprom() const + { return _recover_mb_eeprom.get(); } - bool get_ignore_cal_file() const { + bool get_ignore_cal_file() const + { return _ignore_cal_file.get(); } // must be a number in the string // default NIUSRPRIO_DEFAULT_RPC_PORT - std::string get_niusrprio_rpc_port() const { + std::string get_niusrprio_rpc_port() const + { return std::to_string(_niusrprio_rpc_port.get()); } - std::string get_resource() const { + std::string get_resource() const + { return _resource.get(); } // must be valid file, key == fw, default x300::FW_FILE_NAME - std::string get_fw_file() const { + std::string get_fw_file() const + { return _fw_file.get(); } // true if the key is set - bool has_fw_file() const { + bool has_fw_file() const + { return _has_fw_file.get(); } - bool get_blank_eeprom() const { + bool get_blank_eeprom() const + { return _blank_eeprom.get(); } - bool get_enable_tx_dual_eth() const { + bool get_enable_tx_dual_eth() const + { return _enable_tx_dual_eth.get(); } - inline virtual std::string to_string() const { - return _master_clock_rate.to_string() + ", " + - ""; + inline virtual std::string to_string() const + { + return _master_clock_rate.to_string() + ", " + ""; } private: - virtual void _parse(const device_addr_t& dev_args) { - //Extract parameters from dev_args + virtual void _parse(const device_addr_t& dev_args) + { + // Extract parameters from dev_args #define PARSE_DEFAULT(arg) parse_arg_default(dev_args, arg); PARSE_DEFAULT(_master_clock_rate) if (dev_args.has_key(_master_clock_rate.key())) { @@ -118,14 +137,12 @@ private: // Some daughterboards may require other rates, but this default // works best for all newer daughterboards (i.e. CBX, WBX, SBX, // UBX, and TwinRX). - if (_master_clock_rate.get() >= MIN_TICK_RATE && - _master_clock_rate.get() <= MAX_TICK_RATE) { + if (_master_clock_rate.get() >= MIN_TICK_RATE + && _master_clock_rate.get() <= MAX_TICK_RATE) { _dboard_clock_rate.set(_master_clock_rate.get() / 4); } else { - throw uhd::value_error( - "Can't infer daughterboard clock rate. Specify " - "dboard_clk_rate in the device args." - ); + throw uhd::value_error("Can't infer daughterboard clock rate. Specify " + "dboard_clk_rate in the device args."); } } PARSE_DEFAULT(_system_ref_rate) @@ -152,11 +169,11 @@ private: PARSE_DEFAULT(_fw_file); } PARSE_DEFAULT(_blank_eeprom) - if (dev_args.has_key("enable_tx_dual_eth")){ + if (dev_args.has_key("enable_tx_dual_eth")) { _enable_tx_dual_eth.set(true); } - //Sanity check params + // Sanity check params _enforce_range(_master_clock_rate, MIN_TICK_RATE, MAX_TICK_RATE); _enforce_discrete(_system_ref_rate, EXTERNAL_FREQ_OPTIONS); _enforce_discrete(_clock_source, CLOCK_SOURCE_OPTIONS); @@ -164,26 +181,26 @@ private: // TODO: If _fw_file is set, make sure it's actually a file } - constrained_device_args_t::num_arg<double> _master_clock_rate; - constrained_device_args_t::num_arg<double> _dboard_clock_rate; - constrained_device_args_t::num_arg<double> _system_ref_rate; - constrained_device_args_t::str_arg<false> _clock_source; - constrained_device_args_t::str_arg<false> _time_source; - constrained_device_args_t::str_arg<false> _first_addr; - constrained_device_args_t::str_arg<false> _second_addr; - constrained_device_args_t::str_arg<true> _resource; - constrained_device_args_t::bool_arg _self_cal_adc_delay; - constrained_device_args_t::bool_arg _ext_adc_self_test; - constrained_device_args_t::num_arg<double> _ext_adc_self_test_duration; - constrained_device_args_t::bool_arg _recover_mb_eeprom; - constrained_device_args_t::bool_arg _ignore_cal_file; - constrained_device_args_t::num_arg<size_t> _niusrprio_rpc_port; - constrained_device_args_t::bool_arg _has_fw_file; - constrained_device_args_t::str_arg<true> _fw_file; - constrained_device_args_t::bool_arg _blank_eeprom; - constrained_device_args_t::bool_arg _enable_tx_dual_eth; + constrained_device_args_t::num_arg<double> _master_clock_rate; + constrained_device_args_t::num_arg<double> _dboard_clock_rate; + constrained_device_args_t::num_arg<double> _system_ref_rate; + constrained_device_args_t::str_arg<false> _clock_source; + constrained_device_args_t::str_arg<false> _time_source; + constrained_device_args_t::str_arg<false> _first_addr; + constrained_device_args_t::str_arg<false> _second_addr; + constrained_device_args_t::str_arg<true> _resource; + constrained_device_args_t::bool_arg _self_cal_adc_delay; + constrained_device_args_t::bool_arg _ext_adc_self_test; + constrained_device_args_t::num_arg<double> _ext_adc_self_test_duration; + constrained_device_args_t::bool_arg _recover_mb_eeprom; + constrained_device_args_t::bool_arg _ignore_cal_file; + constrained_device_args_t::num_arg<size_t> _niusrprio_rpc_port; + constrained_device_args_t::bool_arg _has_fw_file; + constrained_device_args_t::str_arg<true> _fw_file; + constrained_device_args_t::bool_arg _blank_eeprom; + constrained_device_args_t::bool_arg _enable_tx_dual_eth; }; -}}} //namespace +}}} // namespace uhd::usrp::x300 -#endif //INCLUDED_X300_DEV_ARGS_HPP +#endif // INCLUDED_X300_DEV_ARGS_HPP diff --git a/host/lib/usrp/x300/x300_fw_ctrl.cpp b/host/lib/usrp/x300/x300_fw_ctrl.cpp index 21c64b509..cbe48bfe8 100644 --- a/host/lib/usrp/x300/x300_fw_ctrl.cpp +++ b/host/lib/usrp/x300/x300_fw_ctrl.cpp @@ -5,18 +5,18 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/types/wb_iface.hpp> #include "x300_fw_common.h" +#include "x300_regs.hpp" +#include <uhd/exception.hpp> +#include <uhd/transport/nirio/niriok_proxy.h> +#include <uhd/transport/nirio/status.h> #include <uhd/transport/udp_simple.hpp> +#include <uhd/types/wb_iface.hpp> #include <uhd/utils/byteswap.hpp> #include <uhd/utils/log.hpp> -#include <uhd/exception.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/format.hpp> #include <boost/thread/mutex.hpp> -#include <uhd/transport/nirio/status.h> -#include <uhd/transport/nirio/niriok_proxy.h> -#include "x300_regs.hpp" -#include <boost/date_time/posix_time/posix_time.hpp> #include <chrono> #include <thread> @@ -26,7 +26,7 @@ using namespace uhd::niusrprio; class x300_ctrl_iface : public wb_iface { public: - enum {num_retries = 3}; + enum { num_retries = 3 }; x300_ctrl_iface(bool enable_errors = true) : errors(enable_errors) { @@ -41,39 +41,37 @@ public: void poke32(const wb_addr_type addr, const uint32_t data) { - for (size_t i = 1; i <= num_retries; i++) - { + for (size_t i = 1; i <= num_retries; i++) { boost::mutex::scoped_lock lock(reg_access); - try - { + try { return this->__poke32(addr, data); - } - catch(const uhd::io_error &ex) - { - std::string error_msg = str(boost::format( - "%s: x300 fw communication failure #%u\n%s") % __loc_info() % i % ex.what()); - if (errors) UHD_LOGGER_ERROR("X300") << error_msg ; - if (i == num_retries) throw uhd::io_error(error_msg); + } catch (const uhd::io_error& ex) { + std::string error_msg = + str(boost::format("%s: x300 fw communication failure #%u\n%s") + % __loc_info() % i % ex.what()); + if (errors) + UHD_LOGGER_ERROR("X300") << error_msg; + if (i == num_retries) + throw uhd::io_error(error_msg); } } } uint32_t peek32(const wb_addr_type addr) { - for (size_t i = 1; i <= num_retries; i++) - { + for (size_t i = 1; i <= num_retries; i++) { boost::mutex::scoped_lock lock(reg_access); - try - { + try { uint32_t data = this->__peek32(addr); return data; - } - catch(const uhd::io_error &ex) - { - std::string error_msg = str(boost::format( - "%s: x300 fw communication failure #%u\n%s") % __loc_info() % i % ex.what()); - if (errors) UHD_LOGGER_ERROR("X300") << error_msg ; - if (i == num_retries) throw uhd::io_error(error_msg); + } catch (const uhd::io_error& ex) { + std::string error_msg = + str(boost::format("%s: x300 fw communication failure #%u\n%s") + % __loc_info() % i % ex.what()); + if (errors) + UHD_LOGGER_ERROR("X300") << error_msg; + if (i == num_retries) + throw uhd::io_error(error_msg); } } return 0; @@ -83,9 +81,9 @@ protected: bool errors; virtual void __poke32(const wb_addr_type addr, const uint32_t data) = 0; - virtual uint32_t __peek32(const wb_addr_type addr) = 0; - virtual void __flush() = 0; - virtual std::string __loc_info() = 0; + virtual uint32_t __peek32(const wb_addr_type addr) = 0; + virtual void __flush() = 0; + virtual std::string __loc_info() = 0; boost::mutex reg_access; }; @@ -97,39 +95,40 @@ protected: class x300_ctrl_iface_enet : public x300_ctrl_iface { public: - x300_ctrl_iface_enet(uhd::transport::udp_simple::sptr udp, bool enable_errors = true): - x300_ctrl_iface(enable_errors), udp(udp), seq(0) + x300_ctrl_iface_enet(uhd::transport::udp_simple::sptr udp, bool enable_errors = true) + : x300_ctrl_iface(enable_errors), udp(udp), seq(0) { - try - { + try { this->peek32(0); + } catch (...) { } - catch(...){} } protected: virtual void __poke32(const wb_addr_type addr, const uint32_t data) { - //load request struct + // load request struct x300_fw_comms_t request = x300_fw_comms_t(); - request.flags = uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK | X300_FW_COMMS_FLAGS_POKE32); + request.flags = + uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK | X300_FW_COMMS_FLAGS_POKE32); request.sequence = uhd::htonx<uint32_t>(seq++); - request.addr = uhd::htonx(addr); - request.data = uhd::htonx(data); + request.addr = uhd::htonx(addr); + request.data = uhd::htonx(data); - //send request + // send request __flush(); udp->send(boost::asio::buffer(&request, sizeof(request))); - //recv reply + // recv reply x300_fw_comms_t reply = x300_fw_comms_t(); const size_t nbytes = udp->recv(boost::asio::buffer(&reply, sizeof(reply)), 1.0); - if (nbytes == 0) throw uhd::io_error("x300 fw poke32 - reply timed out"); + if (nbytes == 0) + throw uhd::io_error("x300 fw poke32 - reply timed out"); - //sanity checks + // sanity checks const size_t flags = uhd::ntohx<uint32_t>(reply.flags); UHD_ASSERT_THROW(nbytes == sizeof(reply)); - UHD_ASSERT_THROW(not (flags & X300_FW_COMMS_FLAGS_ERROR)); + UHD_ASSERT_THROW(not(flags & X300_FW_COMMS_FLAGS_ERROR)); UHD_ASSERT_THROW(flags & X300_FW_COMMS_FLAGS_POKE32); UHD_ASSERT_THROW(flags & X300_FW_COMMS_FLAGS_ACK); UHD_ASSERT_THROW(reply.sequence == request.sequence); @@ -139,39 +138,42 @@ protected: virtual uint32_t __peek32(const wb_addr_type addr) { - //load request struct + // load request struct x300_fw_comms_t request = x300_fw_comms_t(); - request.flags = uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK | X300_FW_COMMS_FLAGS_PEEK32); + request.flags = + uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK | X300_FW_COMMS_FLAGS_PEEK32); request.sequence = uhd::htonx<uint32_t>(seq++); - request.addr = uhd::htonx(addr); - request.data = 0; + request.addr = uhd::htonx(addr); + request.data = 0; - //send request + // send request __flush(); udp->send(boost::asio::buffer(&request, sizeof(request))); - //recv reply + // recv reply x300_fw_comms_t reply = x300_fw_comms_t(); const size_t nbytes = udp->recv(boost::asio::buffer(&reply, sizeof(reply)), 1.0); - if (nbytes == 0) throw uhd::io_error("x300 fw peek32 - reply timed out"); + if (nbytes == 0) + throw uhd::io_error("x300 fw peek32 - reply timed out"); - //sanity checks + // sanity checks const size_t flags = uhd::ntohx<uint32_t>(reply.flags); UHD_ASSERT_THROW(nbytes == sizeof(reply)); - UHD_ASSERT_THROW(not (flags & X300_FW_COMMS_FLAGS_ERROR)); + UHD_ASSERT_THROW(not(flags & X300_FW_COMMS_FLAGS_ERROR)); UHD_ASSERT_THROW(flags & X300_FW_COMMS_FLAGS_PEEK32); UHD_ASSERT_THROW(flags & X300_FW_COMMS_FLAGS_ACK); UHD_ASSERT_THROW(reply.sequence == request.sequence); UHD_ASSERT_THROW(reply.addr == request.addr); - //return result! + // return result! return uhd::ntohx<uint32_t>(reply.data); } virtual void __flush(void) { char buff[X300_FW_COMMS_MTU] = {}; - while (udp->recv(boost::asio::buffer(buff), 0.0)){} //flush + while (udp->recv(boost::asio::buffer(buff), 0.0)) { + } // flush } virtual std::string __loc_info(void) @@ -191,61 +193,66 @@ private: class x300_ctrl_iface_pcie : public x300_ctrl_iface { public: - x300_ctrl_iface_pcie(niriok_proxy::sptr drv_proxy, bool enable_errors = true): - x300_ctrl_iface(enable_errors), _drv_proxy(drv_proxy) + x300_ctrl_iface_pcie(niriok_proxy::sptr drv_proxy, bool enable_errors = true) + : x300_ctrl_iface(enable_errors), _drv_proxy(drv_proxy) { nirio_status status = 0; - nirio_status_chain(_drv_proxy->set_attribute(RIO_ADDRESS_SPACE, BUS_INTERFACE), status); + nirio_status_chain( + _drv_proxy->set_attribute(RIO_ADDRESS_SPACE, BUS_INTERFACE), status); - //Verify that the Ettus FPGA loaded in the device. This may not be true if the - //user is switching to UHD after using LabVIEW FPGA. + // Verify that the Ettus FPGA loaded in the device. This may not be true if the + // user is switching to UHD after using LabVIEW FPGA. uint32_t pcie_fpga_signature = 0; _drv_proxy->peek(FPGA_PCIE_SIG_REG, pcie_fpga_signature); if (pcie_fpga_signature != FPGA_X3xx_SIG_VALUE) - throw uhd::io_error("cannot create x300_ctrl_iface_pcie. incorrect/no fpga image"); + throw uhd::io_error( + "cannot create x300_ctrl_iface_pcie. incorrect/no fpga image"); - //Also, poll on the ZPU_STATUS bit to ensure all the state machines in the FPGA are - //ready to accept register transaction requests. + // Also, poll on the ZPU_STATUS bit to ensure all the state machines in the FPGA + // are ready to accept register transaction requests. uint32_t reg_data = 0xffffffff; - boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time(); + boost::posix_time::ptime start_time = + boost::posix_time::microsec_clock::local_time(); boost::posix_time::time_duration elapsed; do { - std::this_thread::sleep_for(std::chrono::microseconds(500)); //Avoid flooding the bus + std::this_thread::sleep_for( + std::chrono::microseconds(500)); // Avoid flooding the bus elapsed = boost::posix_time::microsec_clock::local_time() - start_time; - nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_STATUS_REG(0), reg_data), status); - } while ( - nirio_status_not_fatal(status) && - (reg_data & PCIE_ZPU_STATUS_SUSPENDED) && - elapsed.total_milliseconds() < INIT_TIMEOUT_IN_MS); + nirio_status_chain( + _drv_proxy->peek(PCIE_ZPU_STATUS_REG(0), reg_data), status); + } while (nirio_status_not_fatal(status) && (reg_data & PCIE_ZPU_STATUS_SUSPENDED) + && elapsed.total_milliseconds() < INIT_TIMEOUT_IN_MS); nirio_status_to_exception(status, "Could not initialize x300_ctrl_iface_pcie."); - try - { + try { this->peek32(0); + } catch (...) { } - catch(...){} } protected: virtual void __poke32(const wb_addr_type addr, const uint32_t data) { nirio_status status = 0; - uint32_t reg_data = 0xffffffff; - boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time(); + uint32_t reg_data = 0xffffffff; + boost::posix_time::ptime start_time = + boost::posix_time::microsec_clock::local_time(); boost::posix_time::time_duration elapsed; nirio_status_chain(_drv_proxy->poke(PCIE_ZPU_DATA_REG(addr), data), status); if (nirio_status_not_fatal(status)) { do { - std::this_thread::sleep_for(std::chrono::microseconds(50)); //Avoid flooding the bus + std::this_thread::sleep_for( + std::chrono::microseconds(50)); // Avoid flooding the bus elapsed = boost::posix_time::microsec_clock::local_time() - start_time; - nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status); + nirio_status_chain( + _drv_proxy->peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status); } while ( - nirio_status_not_fatal(status) && - ((reg_data & (PCIE_ZPU_STATUS_BUSY | PCIE_ZPU_STATUS_SUSPENDED)) != 0) && - elapsed.total_milliseconds() < READ_TIMEOUT_IN_MS); + nirio_status_not_fatal(status) + && ((reg_data & (PCIE_ZPU_STATUS_BUSY | PCIE_ZPU_STATUS_SUSPENDED)) != 0) + && elapsed.total_milliseconds() < READ_TIMEOUT_IN_MS); } if (nirio_status_fatal(status)) @@ -257,20 +264,24 @@ protected: virtual uint32_t __peek32(const wb_addr_type addr) { nirio_status status = 0; - uint32_t reg_data = 0xffffffff; - boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time(); + uint32_t reg_data = 0xffffffff; + boost::posix_time::ptime start_time = + boost::posix_time::microsec_clock::local_time(); boost::posix_time::time_duration elapsed; - nirio_status_chain(_drv_proxy->poke(PCIE_ZPU_READ_REG(addr), PCIE_ZPU_READ_START), status); + nirio_status_chain( + _drv_proxy->poke(PCIE_ZPU_READ_REG(addr), PCIE_ZPU_READ_START), status); if (nirio_status_not_fatal(status)) { do { - std::this_thread::sleep_for(std::chrono::microseconds(50)); //Avoid flooding the bus + std::this_thread::sleep_for( + std::chrono::microseconds(50)); // Avoid flooding the bus elapsed = boost::posix_time::microsec_clock::local_time() - start_time; - nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status); + nirio_status_chain( + _drv_proxy->peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status); } while ( - nirio_status_not_fatal(status) && - ((reg_data & (PCIE_ZPU_STATUS_BUSY | PCIE_ZPU_STATUS_SUSPENDED)) != 0) && - elapsed.total_milliseconds() < READ_TIMEOUT_IN_MS); + nirio_status_not_fatal(status) + && ((reg_data & (PCIE_ZPU_STATUS_BUSY | PCIE_ZPU_STATUS_SUSPENDED)) != 0) + && elapsed.total_milliseconds() < READ_TIMEOUT_IN_MS); } nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_DATA_REG(addr), reg_data), status); @@ -298,12 +309,14 @@ private: static const uint32_t INIT_TIMEOUT_IN_MS = 5000; }; -wb_iface::sptr x300_make_ctrl_iface_enet(uhd::transport::udp_simple::sptr udp, bool enable_errors = true) +wb_iface::sptr x300_make_ctrl_iface_enet( + uhd::transport::udp_simple::sptr udp, bool enable_errors = true) { return wb_iface::sptr(new x300_ctrl_iface_enet(udp, enable_errors)); } -wb_iface::sptr x300_make_ctrl_iface_pcie(niriok_proxy::sptr drv_proxy, bool enable_errors = true) +wb_iface::sptr x300_make_ctrl_iface_pcie( + niriok_proxy::sptr drv_proxy, bool enable_errors = true) { return wb_iface::sptr(new x300_ctrl_iface_pcie(drv_proxy, enable_errors)); } diff --git a/host/lib/usrp/x300/x300_fw_uart.cpp b/host/lib/usrp/x300/x300_fw_uart.cpp index 912d977ed..0dde87da5 100644 --- a/host/lib/usrp/x300/x300_fw_uart.cpp +++ b/host/lib/usrp/x300/x300_fw_uart.cpp @@ -6,11 +6,11 @@ // #include "x300_impl.hpp" -#include <uhd/types/wb_iface.hpp> #include "x300_regs.hpp" -#include <uhd/utils/log.hpp> -#include <uhd/types/serial.hpp> #include <uhd/exception.hpp> +#include <uhd/types/serial.hpp> +#include <uhd/types/wb_iface.hpp> +#include <uhd/utils/log.hpp> #include <boost/format.hpp> #include <chrono> @@ -18,44 +18,42 @@ using namespace uhd; struct x300_uart_iface : uart_iface { - x300_uart_iface(wb_iface::sptr iface): - _iface(iface), - rxoffset(0), - txword32(0), - _last_device_rxoffset(0) + x300_uart_iface(wb_iface::sptr iface) + : _iface(iface), rxoffset(0), txword32(0), _last_device_rxoffset(0) { - txoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX)); + txoffset = + _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX)); rxpool = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_ADDR)); txpool = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_ADDR)); - poolsize = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_WORDS32)); + poolsize = + _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_WORDS32)); _rxcache.resize(poolsize); - //this->write_uart("HELLO UART\n"); - //this->read_uart(0.1); + // this->write_uart("HELLO UART\n"); + // this->read_uart(0.1); } void putchar(const char ch) { - const int shift = ((txoffset%4) * 8); - if (shift == 0) txword32 = 0; + const int shift = ((txoffset % 4) * 8); + if (shift == 0) + txword32 = 0; txword32 |= uint32_t(ch) << shift; // Write out full 32 bit words or whatever we have if end of string - if (txoffset % 4 == 3 or ch == '\n') - { - _iface->poke32(SR_ADDR(txpool, txoffset/4), txword32); + if (txoffset % 4 == 3 or ch == '\n') { + _iface->poke32(SR_ADDR(txpool, txoffset / 4), txword32); } - txoffset = (txoffset + 1) % (poolsize*4); - if (ch == '\n') - { + txoffset = (txoffset + 1) % (poolsize * 4); + if (ch == '\n') { // Tell the X300 to write the string - _iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX), txoffset); + _iface->poke32( + SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_INDEX), txoffset); } } - void write_uart(const std::string &buff) + void write_uart(const std::string& buff) { boost::mutex::scoped_lock lock(_write_mutex); - for(const char ch: buff) - { + for (const char ch : buff) { this->putchar(ch); } } @@ -65,60 +63,57 @@ struct x300_uart_iface : uart_iface if (rxoffset == _last_device_rxoffset) return -1; - int ret = static_cast<int>(_rxcache[((rxoffset)/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF); + int ret = static_cast<int>( + _rxcache[((rxoffset) / 4) % poolsize] >> ((rxoffset % 4) * 8) & 0xFF); rxoffset++; return ret; } void update_cache(void) { - uint32_t device_rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX)); + uint32_t device_rxoffset = + _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX)); uint32_t delta = device_rxoffset - rxoffset; - while (delta) - { - if (delta >= poolsize*4) - { + while (delta) { + if (delta >= poolsize * 4) { // all the data is new - reload the entire cache - for (uint32_t i = 0; i < poolsize; i++) - { + for (uint32_t i = 0; i < poolsize; i++) { _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i)); } // set the head to the same character as the current device // offset (tail) one loop earlier - rxoffset = device_rxoffset - (poolsize*4); + rxoffset = device_rxoffset - (poolsize * 4); // set the tail to the current device offset _last_device_rxoffset = device_rxoffset; // the string at the head is a partial, so skip it - for (int c = getchar(); c != '\n' and c != -1; c = getchar()) {} + for (int c = getchar(); c != '\n' and c != -1; c = getchar()) { + } // clear the partial string in the buffer, if any _rxbuff.clear(); - } - else if (rxoffset == _last_device_rxoffset) - { + } else if (rxoffset == _last_device_rxoffset) { // new data was added - refresh the portion of the cache that was updated - for (uint32_t i = (_last_device_rxoffset/4) % poolsize; - i != ((device_rxoffset/4)+1) % poolsize; - i = (i+1) % poolsize) - { + for (uint32_t i = (_last_device_rxoffset / 4) % poolsize; + i != ((device_rxoffset / 4) + 1) % poolsize; + i = (i + 1) % poolsize) { _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i)); } // set the tail to the current device offset _last_device_rxoffset = device_rxoffset; - } - else - { - // there is new data, but we aren't done with what we have - check back later + } else { + // there is new data, but we aren't done with what we have - check back + // later break; } // check again to see if anything changed while we were updating the cache - device_rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX)); + device_rxoffset = + _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX)); delta = device_rxoffset - rxoffset; } } @@ -126,26 +121,22 @@ struct x300_uart_iface : uart_iface std::string read_uart(double timeout) { boost::mutex::scoped_lock lock(_read_mutex); - const auto exit_time = - std::chrono::steady_clock::now() - + std::chrono::microseconds(int64_t(timeout*1e6)); + const auto exit_time = std::chrono::steady_clock::now() + + std::chrono::microseconds(int64_t(timeout * 1e6)); std::string buff; - while (true) - { + while (true) { // Update cache this->update_cache(); // Get available characters - for (int ch = this->getchar(); ch != -1; ch = this->getchar()) - { + for (int ch = this->getchar(); ch != -1; ch = this->getchar()) { // store character to buffer _rxbuff.append(1, ch); // newline found - return string - if (ch == '\n') - { + if (ch == '\n') { buff.swap(_rxbuff); return buff; } diff --git a/host/lib/usrp/x300/x300_image_loader.cpp b/host/lib/usrp/x300/x300_image_loader.cpp index 4e2c9e580..5cb1f1b85 100644 --- a/host/lib/usrp/x300/x300_image_loader.cpp +++ b/host/lib/usrp/x300/x300_image_loader.cpp @@ -5,28 +5,25 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <fstream> -#include <vector> - -#include <boost/algorithm/string.hpp> -#include <boost/filesystem.hpp> -#include <boost/property_tree/ptree.hpp> -#include <boost/property_tree/xml_parser.hpp> - +#include "cdecode.h" +#include "x300_fw_common.h" +#include "x300_impl.hpp" #include <uhd/config.hpp> #include <uhd/device.hpp> -#include <uhd/image_loader.hpp> #include <uhd/exception.hpp> -#include <uhd/transport/udp_simple.hpp> +#include <uhd/image_loader.hpp> #include <uhd/transport/nirio/niusrprio_session.h> #include <uhd/transport/nirio/status.h> +#include <uhd/transport/udp_simple.hpp> #include <uhd/utils/byteswap.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/static.hpp> - -#include "x300_impl.hpp" -#include "x300_fw_common.h" -#include "cdecode.h" +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp> +#include <fstream> +#include <vector> namespace fs = boost::filesystem; @@ -50,65 +47,81 @@ using namespace uhd::transport; /* * Bitstream header pattern */ -static const uint8_t X300_FPGA_BIT_HEADER[] = -{ - 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, - 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61, 0x00 -}; +static const uint8_t X300_FPGA_BIT_HEADER[] = {0x00, + 0x09, + 0x0f, + 0xf0, + 0x0f, + 0xf0, + 0x0f, + 0xf0, + 0x0f, + 0xf0, + 0x00, + 0x00, + 0x01, + 0x61, + 0x00}; /* * Packet structure */ -typedef struct { +typedef struct +{ uint32_t flags; uint32_t sector; uint32_t index; uint32_t size; union { - uint8_t data8[X300_PACKET_SIZE_BYTES]; - uint16_t data16[X300_PACKET_SIZE_BYTES/2]; + uint8_t data8[X300_PACKET_SIZE_BYTES]; + uint16_t data16[X300_PACKET_SIZE_BYTES / 2]; }; } x300_fpga_update_data_t; /* * X-Series burn session */ -typedef struct { - bool found; - bool ethernet; - bool configure; // Reload FPGA after burning to flash (Ethernet only) - bool verify; // Device will verify the download along the way (Ethernet only) - bool download; // Host will read the FPGA image on the device to a file - bool lvbitx; - uhd::device_addr_t dev_addr; - std::string ip_addr; - std::string fpga_type; - std::string resource; - std::string filepath; - std::string outpath; - std::string rpc_port; - udp_simple::sptr write_xport; - udp_simple::sptr read_xport; - size_t size; - uint8_t data_in[udp_simple::mtu]; - std::vector<char> bitstream; // .bin image extracted from .lvbitx file +typedef struct +{ + bool found; + bool ethernet; + bool configure; // Reload FPGA after burning to flash (Ethernet only) + bool verify; // Device will verify the download along the way (Ethernet only) + bool download; // Host will read the FPGA image on the device to a file + bool lvbitx; + uhd::device_addr_t dev_addr; + std::string ip_addr; + std::string fpga_type; + std::string resource; + std::string filepath; + std::string outpath; + std::string rpc_port; + udp_simple::sptr write_xport; + udp_simple::sptr read_xport; + size_t size; + uint8_t data_in[udp_simple::mtu]; + std::vector<char> bitstream; // .bin image extracted from .lvbitx file } x300_session_t; /* * Extract the .bin image from the given LVBITX file. */ -static void extract_from_lvbitx(x300_session_t &session){ - boost::property_tree::ptree pt; - boost::property_tree::xml_parser::read_xml(session.filepath.c_str(), pt, - boost::property_tree::xml_parser::no_comments | - boost::property_tree::xml_parser::trim_whitespace); +static void extract_from_lvbitx(x300_session_t& session) +{ + boost::property_tree::ptree pt; + boost::property_tree::xml_parser::read_xml(session.filepath.c_str(), + pt, + boost::property_tree::xml_parser::no_comments + | boost::property_tree::xml_parser::trim_whitespace); const std::string encoded_bitstream(pt.get<std::string>("Bitfile.Bitstream")); std::vector<char> decoded_bitstream(encoded_bitstream.size()); base64_decodestate decode_state; base64_init_decodestate(&decode_state); const size_t decoded_size = base64_decode_block(encoded_bitstream.c_str(), - encoded_bitstream.size(), &decoded_bitstream.front(), &decode_state); + encoded_bitstream.size(), + &decoded_bitstream.front(), + &decode_state); decoded_bitstream.resize(decoded_size); session.bitstream.swap(decoded_bitstream); @@ -118,118 +131,122 @@ static void extract_from_lvbitx(x300_session_t &session){ /* * Validate X300 image and extract if LVBITX. */ -static void x300_validate_image(x300_session_t &session){ - if(not fs::exists(session.filepath)){ - throw uhd::runtime_error(str(boost::format("Could not find image at path \"%s\".") - % session.filepath)); +static void x300_validate_image(x300_session_t& session) +{ + if (not fs::exists(session.filepath)) { + throw uhd::runtime_error(str( + boost::format("Could not find image at path \"%s\".") % session.filepath)); } std::string extension = fs::extension(session.filepath); - session.lvbitx = (extension == ".lvbitx"); + session.lvbitx = (extension == ".lvbitx"); - if(session.lvbitx){ + if (session.lvbitx) { extract_from_lvbitx(session); - if(session.size > X300_FPGA_BIN_SIZE_BYTES){ - throw uhd::runtime_error(str(boost::format("The specified FPGA image is too large: %d vs. %d") - % session.size % X300_FPGA_BIN_SIZE_BYTES)); + if (session.size > X300_FPGA_BIN_SIZE_BYTES) { + throw uhd::runtime_error( + str(boost::format("The specified FPGA image is too large: %d vs. %d") + % session.size % X300_FPGA_BIN_SIZE_BYTES)); } /* * PCIe burning just takes a filepath, even for a .lvbitx file, * so just extract it to validate the size. */ - if(!session.ethernet) session.bitstream.clear(); - } - else if(extension == ".bin" or extension == ".bit"){ + if (!session.ethernet) + session.bitstream.clear(); + } else if (extension == ".bin" or extension == ".bit") { uint32_t max_size = (extension == ".bin") ? X300_FPGA_BIN_SIZE_BYTES - : X300_FPGA_BIT_SIZE_BYTES; + : X300_FPGA_BIT_SIZE_BYTES; session.size = fs::file_size(session.filepath); - if(session.size > max_size){ - throw uhd::runtime_error(str(boost::format("The specified FPGA image is too large: %d vs. %d") - % session.size % max_size)); + if (session.size > max_size) { + throw uhd::runtime_error( + str(boost::format("The specified FPGA image is too large: %d vs. %d") + % session.size % max_size)); return; } - } - else{ - throw uhd::runtime_error(str(boost::format("Invalid extension \"%s\". Extension must be .bin, .bit, or .lvbitx.") - % extension)); + } else { + throw uhd::runtime_error( + str(boost::format( + "Invalid extension \"%s\". Extension must be .bin, .bit, or .lvbitx.") + % extension)); } } -static void x300_setup_session(x300_session_t &session, - const device_addr_t &args, - const std::string &filepath, - const std::string &outpath){ +static void x300_setup_session(x300_session_t& session, + const device_addr_t& args, + const std::string& filepath, + const std::string& outpath) +{ device_addrs_t devs = x300_find(args); - if(devs.size() == 0){ + if (devs.size() == 0) { session.found = false; return; - } - else if(devs.size() > 1){ - std::string err_msg = "Could not resolve given args to a single X-Series device.\n" - "Applicable devices:\n"; - - for(const uhd::device_addr_t &dev: devs){ - std::string identifier = dev.has_key("addr") ? "addr" - : "resource"; - - err_msg += str(boost::format(" * %s (%s=%s)\n") - % dev.get("product", "X3XX") - % identifier - % dev.get(identifier)); + } else if (devs.size() > 1) { + std::string err_msg = + "Could not resolve given args to a single X-Series device.\n" + "Applicable devices:\n"; + + for (const uhd::device_addr_t& dev : devs) { + std::string identifier = dev.has_key("addr") ? "addr" : "resource"; + + err_msg += str(boost::format(" * %s (%s=%s)\n") % dev.get("product", "X3XX") + % identifier % dev.get(identifier)); } - err_msg += "\nSpecify one of these devices with the given args to load an image onto it."; + err_msg += "\nSpecify one of these devices with the given args to load an image " + "onto it."; throw uhd::runtime_error(err_msg); } - session.found = true; + session.found = true; session.dev_addr = devs[0]; session.ethernet = session.dev_addr.has_key("addr"); - if(session.ethernet){ - session.ip_addr = session.dev_addr["addr"]; - session.configure = args.has_key("configure"); - session.write_xport = udp_simple::make_connected(session.ip_addr, - BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT)); - session.read_xport = udp_simple::make_connected(session.ip_addr, - BOOST_STRINGIZE(X300_FPGA_READ_UDP_PORT)); - session.verify = args.has_key("verify"); + if (session.ethernet) { + session.ip_addr = session.dev_addr["addr"]; + session.configure = args.has_key("configure"); + session.write_xport = udp_simple::make_connected( + session.ip_addr, BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT)); + session.read_xport = udp_simple::make_connected( + session.ip_addr, BOOST_STRINGIZE(X300_FPGA_READ_UDP_PORT)); + session.verify = args.has_key("verify"); session.download = args.has_key("download"); - } - else{ + } else { session.resource = session.dev_addr["resource"]; session.rpc_port = args.get("rpc-port", "5444"); } /* - * The user can specify an FPGA type (1G, HGS, XGS), rather than a filename. If the user - * does not specify one, this will default to the type currently on the device. If this - * cannot be determined, then the user is forced to specify a filename. + * The user can specify an FPGA type (1G, HGS, XGS), rather than a filename. If the + * user does not specify one, this will default to the type currently on the device. + * If this cannot be determined, then the user is forced to specify a filename. */ session.fpga_type = args.get("fpga", session.dev_addr.get("fpga", "")); - if(filepath == ""){ - if(!session.dev_addr.has_key("product") or session.fpga_type == ""){ - throw uhd::runtime_error("Found a device but could not auto-generate an image filename."); - } - else session.filepath = find_image_path(str(boost::format("usrp_%s_fpga_%s.bit") - % (to_lower_copy(session.dev_addr["product"])) - % session.fpga_type)); - } - else session.filepath = filepath; + if (filepath == "") { + if (!session.dev_addr.has_key("product") or session.fpga_type == "") { + throw uhd::runtime_error( + "Found a device but could not auto-generate an image filename."); + } else + session.filepath = find_image_path( + str(boost::format("usrp_%s_fpga_%s.bit") + % (to_lower_copy(session.dev_addr["product"])) % session.fpga_type)); + } else + session.filepath = filepath; /* * The user can specify an output image path, or UHD will use the * system temporary path by default */ - if(outpath == ""){ - if(!session.dev_addr.has_key("product") or session.fpga_type == ""){ - throw uhd::runtime_error("Found a device but could not auto-generate an image filename."); + if (outpath == "") { + if (!session.dev_addr.has_key("product") or session.fpga_type == "") { + throw uhd::runtime_error( + "Found a device but could not auto-generate an image filename."); } - std::string filename = str(boost::format("usrp_%s_fpga_%s") - % (to_lower_copy(session.dev_addr["product"])) - % session.fpga_type); + std::string filename = + str(boost::format("usrp_%s_fpga_%s") + % (to_lower_copy(session.dev_addr["product"])) % session.fpga_type); session.outpath = get_tmp_path() + "/" + filename; } else { @@ -244,172 +261,180 @@ static void x300_setup_session(x300_session_t &session, * Ethernet communication functions */ static UHD_INLINE size_t x300_send_and_recv(udp_simple::sptr xport, - uint32_t pkt_code, - x300_fpga_update_data_t *pkt_out, - uint8_t* data){ + uint32_t pkt_code, + x300_fpga_update_data_t* pkt_out, + uint8_t* data) +{ pkt_out->flags = uhd::htonx<uint32_t>(pkt_code); xport->send(boost::asio::buffer(pkt_out, sizeof(*pkt_out))); return xport->recv(boost::asio::buffer(data, udp_simple::mtu), UDP_TIMEOUT); } -static UHD_INLINE bool x300_recv_ok(const x300_fpga_update_data_t *pkt_in, - size_t len){ - return (len > 0 and - ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR) != X300_FPGA_PROG_FLAGS_ERROR)); +static UHD_INLINE bool x300_recv_ok(const x300_fpga_update_data_t* pkt_in, size_t len) +{ + return (len > 0 + and ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR) + != X300_FPGA_PROG_FLAGS_ERROR)); } // Image data needs to be bitswapped -static UHD_INLINE void x300_bitswap(uint8_t *num){ +static UHD_INLINE void x300_bitswap(uint8_t* num) +{ *num = ((*num & 0xF0) >> 4) | ((*num & 0x0F) << 4); *num = ((*num & 0xCC) >> 2) | ((*num & 0x33) << 2); *num = ((*num & 0xAA) >> 1) | ((*num & 0x55) << 1); } -static void x300_ethernet_load(x300_session_t &session){ - +static void x300_ethernet_load(x300_session_t& session) +{ // UDP receive buffer x300_fpga_update_data_t pkt_out; - const x300_fpga_update_data_t *pkt_in = reinterpret_cast<const x300_fpga_update_data_t*>(session.data_in); + const x300_fpga_update_data_t* pkt_in = + reinterpret_cast<const x300_fpga_update_data_t*>(session.data_in); // Initialize write session uint32_t flags = X300_FPGA_PROG_FLAGS_ACK | X300_FPGA_PROG_FLAGS_INIT; - size_t len = x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in); - if(x300_recv_ok(pkt_in, len)){ + size_t len = + x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in); + if (x300_recv_ok(pkt_in, len)) { std::cout << "-- Initializing FPGA loading..." << std::flush; - } - else if(len == 0){ + } else if (len == 0) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else{ + } else { std::cout << "failed." << std::endl; throw uhd::runtime_error("Device reported an error during initialization."); } std::cout << "successful." << std::endl; - if(session.verify){ - std::cout << "-- NOTE: Device is verifying the image it is receiving, increasing the loading time." << std::endl; + if (session.verify) { + std::cout << "-- NOTE: Device is verifying the image it is receiving, increasing " + "the loading time." + << std::endl; } size_t current_pos = 0; - size_t sectors = (session.size / X300_FLASH_SECTOR_SIZE); + size_t sectors = (session.size / X300_FLASH_SECTOR_SIZE); std::ifstream image(session.filepath.c_str(), std::ios::binary); // Each sector - for(size_t i = 0; i < session.size; i += X300_FLASH_SECTOR_SIZE){ - + for (size_t i = 0; i < session.size; i += X300_FLASH_SECTOR_SIZE) { // Print progress percentage at beginning of each sector std::cout << boost::format("\r-- Loading %s FPGA image: %d%% (%d/%d sectors)") - % session.fpga_type - % (int(double(i) / double(session.size) * 100.0)) - % (i / X300_FLASH_SECTOR_SIZE) - % sectors - << std::flush; + % session.fpga_type + % (int(double(i) / double(session.size) * 100.0)) + % (i / X300_FLASH_SECTOR_SIZE) % sectors + << std::flush; // Each packet - for(size_t j = i; (j < session.size and j < (i+X300_FLASH_SECTOR_SIZE)); j += X300_PACKET_SIZE_BYTES){ + for (size_t j = i; (j < session.size and j < (i + X300_FLASH_SECTOR_SIZE)); + j += X300_PACKET_SIZE_BYTES) { flags = X300_FPGA_PROG_FLAGS_ACK; - if(j == i) flags |= X300_FPGA_PROG_FLAGS_ERASE; // Erase at beginning of sector - if(session.verify) flags |= X300_FPGA_PROG_FLAGS_VERIFY; + if (j == i) + flags |= X300_FPGA_PROG_FLAGS_ERASE; // Erase at beginning of sector + if (session.verify) + flags |= X300_FPGA_PROG_FLAGS_VERIFY; // Set burn location - pkt_out.sector = htonx<uint32_t>(X300_FPGA_SECTOR_START + (i/X300_FLASH_SECTOR_SIZE)); - pkt_out.index = htonx<uint32_t>((j % X300_FLASH_SECTOR_SIZE) / 2); - pkt_out.size = htonx<uint32_t>(X300_PACKET_SIZE_BYTES / 2); + pkt_out.sector = + htonx<uint32_t>(X300_FPGA_SECTOR_START + (i / X300_FLASH_SECTOR_SIZE)); + pkt_out.index = htonx<uint32_t>((j % X300_FLASH_SECTOR_SIZE) / 2); + pkt_out.size = htonx<uint32_t>(X300_PACKET_SIZE_BYTES / 2); // Read next piece of image memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES); - if(session.lvbitx){ - memcpy(pkt_out.data8, &session.bitstream[current_pos], X300_PACKET_SIZE_BYTES); + if (session.lvbitx) { + memcpy(pkt_out.data8, + &session.bitstream[current_pos], + X300_PACKET_SIZE_BYTES); current_pos += X300_PACKET_SIZE_BYTES; - } - else{ + } else { image.read((char*)pkt_out.data8, X300_PACKET_SIZE_BYTES); } // Data must be bitswapped and byteswapped - for(size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++){ + for (size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++) { x300_bitswap(&pkt_out.data8[k]); } - for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){ + for (size_t k = 0; k < (X300_PACKET_SIZE_BYTES / 2); k++) { pkt_out.data16[k] = htonx<uint16_t>(pkt_out.data16[k]); } - len = x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in); - if(len == 0){ - if(!session.lvbitx) image.close(); + len = + x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in); + if (len == 0) { + if (!session.lvbitx) + image.close(); throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)){ - if(!session.lvbitx) image.close(); + } else if ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)) { + if (!session.lvbitx) + image.close(); throw uhd::runtime_error("Device reported an error."); } } } - if(!session.lvbitx){ + if (!session.lvbitx) { image.close(); } std::cout << boost::format("\r-- Loading %s FPGA image: 100%% (%d/%d sectors)") - % session.fpga_type - % sectors - % sectors - << std::endl; + % session.fpga_type % sectors % sectors + << std::endl; // Cleanup - if(!session.lvbitx) image.close(); - flags = (X300_FPGA_PROG_FLAGS_CLEANUP | X300_FPGA_PROG_FLAGS_ACK); + if (!session.lvbitx) + image.close(); + flags = (X300_FPGA_PROG_FLAGS_CLEANUP | X300_FPGA_PROG_FLAGS_ACK); pkt_out.sector = pkt_out.index = pkt_out.size = 0; memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES); std::cout << "-- Finalizing image load..." << std::flush; len = x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in); - if(len == 0){ + if (len == 0) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)){ + } else if ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Device reported an error during cleanup."); - } - else std::cout << "successful." << std::endl; + } else + std::cout << "successful." << std::endl; // Save new FPGA image (if option set) - if(session.configure){ + if (session.configure) { flags = (X300_FPGA_PROG_CONFIGURE | X300_FPGA_PROG_FLAGS_ACK); x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in); std::cout << "-- Saving image onto device..." << std::flush; - if(len == 0){ + if (len == 0) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)){ + } else if ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Device reported an error while saving the image."); - } - else std::cout << "successful." << std::endl; + } else + std::cout << "successful." << std::endl; } - std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.") % session.dev_addr.get("product", "")) << std::endl; + std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.") + % session.dev_addr.get("product", "")) + << std::endl; } -static void x300_ethernet_read(x300_session_t &session){ - +static void x300_ethernet_read(x300_session_t& session) +{ // UDP receive buffer x300_fpga_update_data_t pkt_out; memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES); - x300_fpga_update_data_t *pkt_in = reinterpret_cast<x300_fpga_update_data_t*>(session.data_in); + x300_fpga_update_data_t* pkt_in = + reinterpret_cast<x300_fpga_update_data_t*>(session.data_in); // Initialize read session uint32_t flags = X300_FPGA_READ_FLAGS_ACK | X300_FPGA_READ_FLAGS_INIT; size_t len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in); - if(x300_recv_ok(pkt_in, len)){ + if (x300_recv_ok(pkt_in, len)) { std::cout << "-- Initializing FPGA reading..." << std::flush; - } - else if(len == 0){ + } else if (len == 0) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else{ + } else { std::cout << "failed." << std::endl; throw uhd::runtime_error("Device reported an error during initialization."); } @@ -426,83 +451,79 @@ static void x300_ethernet_read(x300_session_t &session){ pkt_out.size = htonx<uint32_t>(X300_PACKET_SIZE_BYTES / 2); len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in); - if(len == 0){ + if (len == 0) { throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)){ + } else if ((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)) { throw uhd::runtime_error("Device reported an error."); } // Data must be bitswapped and byteswapped - for(size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++){ + for (size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++) { x300_bitswap(&pkt_in->data8[k]); } - for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){ + for (size_t k = 0; k < (X300_PACKET_SIZE_BYTES / 2); k++) { pkt_in->data16[k] = htonx<uint16_t>(pkt_in->data16[k]); } // Assume the largest size first size_t image_size = X300_FPGA_BIT_SIZE_BYTES; - size_t sectors = (image_size / X300_FLASH_SECTOR_SIZE); + size_t sectors = (image_size / X300_FLASH_SECTOR_SIZE); std::string extension(".bit"); // Check for the beginning header sequence to determine // the total amount of data (.bit vs .bin) on the flash // The .bit file format includes header information not part of a .bin - for (size_t i = 0; i < sizeof(X300_FPGA_BIT_HEADER); i++) - { - if (pkt_in->data8[i] != X300_FPGA_BIT_HEADER[i]) - { - std::cout << "-- No *.bit header detected, FPGA image is a raw stream (*.bin)!" << std::endl; + for (size_t i = 0; i < sizeof(X300_FPGA_BIT_HEADER); i++) { + if (pkt_in->data8[i] != X300_FPGA_BIT_HEADER[i]) { + std::cout + << "-- No *.bit header detected, FPGA image is a raw stream (*.bin)!" + << std::endl; image_size = X300_FPGA_BIN_SIZE_BYTES; - sectors = (image_size / X300_FLASH_SECTOR_SIZE); - extension = std::string(".bin"); + sectors = (image_size / X300_FLASH_SECTOR_SIZE); + extension = std::string(".bin"); break; } } session.outpath += extension; std::ofstream image(session.outpath.c_str(), std::ios::binary); - std::cout << boost::format("-- Output FPGA file: %s\n") - % session.outpath; + std::cout << boost::format("-- Output FPGA file: %s\n") % session.outpath; // Write the first packet image.write((char*)pkt_in->data8, X300_PACKET_SIZE_BYTES); // Each sector size_t pkt_count = X300_PACKET_SIZE_BYTES; - for(size_t i = 0; i < image_size; i += X300_FLASH_SECTOR_SIZE){ - + for (size_t i = 0; i < image_size; i += X300_FLASH_SECTOR_SIZE) { // Once we determine the image size, print the progress percentage std::cout << boost::format("\r-- Reading %s FPGA image: %d%% (%d/%d sectors)") - % session.fpga_type - % (int(double(i) / double(image_size) * 100.0)) - % (i / X300_FLASH_SECTOR_SIZE) - % sectors + % session.fpga_type + % (int(double(i) / double(image_size) * 100.0)) + % (i / X300_FLASH_SECTOR_SIZE) % sectors << std::flush; // Each packet - while (pkt_count < image_size and pkt_count < (i + X300_FLASH_SECTOR_SIZE)) - { + while (pkt_count < image_size and pkt_count < (i + X300_FLASH_SECTOR_SIZE)) { // Set burn location - pkt_out.sector = htonx<uint32_t>(X300_FPGA_SECTOR_START + (i/X300_FLASH_SECTOR_SIZE)); - pkt_out.index = htonx<uint32_t>((pkt_count % X300_FLASH_SECTOR_SIZE) / 2); + pkt_out.sector = + htonx<uint32_t>(X300_FPGA_SECTOR_START + (i / X300_FLASH_SECTOR_SIZE)); + pkt_out.index = htonx<uint32_t>((pkt_count % X300_FLASH_SECTOR_SIZE) / 2); - len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in); - if(len == 0){ + len = + x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in); + if (len == 0) { image.close(); throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)){ + } else if ((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)) { image.close(); throw uhd::runtime_error("Device reported an error."); } // Data must be bitswapped and byteswapped - for(size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++){ + for (size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++) { x300_bitswap(&pkt_in->data8[k]); } - for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){ + for (size_t k = 0; k < (X300_PACKET_SIZE_BYTES / 2); k++) { pkt_in->data16[k] = htonx<uint16_t>(pkt_in->data16[k]); } @@ -510,8 +531,7 @@ static void x300_ethernet_read(x300_session_t &session){ // If this is the last packet, get rid of the extra zero padding // due to packet size size_t nbytes = X300_PACKET_SIZE_BYTES; - if (pkt_count > (image_size - X300_PACKET_SIZE_BYTES)) - { + if (pkt_count > (image_size - X300_PACKET_SIZE_BYTES)) { nbytes = (image_size - pkt_count); } @@ -526,85 +546,94 @@ static void x300_ethernet_read(x300_session_t &session){ } std::cout << boost::format("\r-- Reading %s FPGA image: 100%% (%d/%d sectors)") - % session.fpga_type - % sectors - % sectors + % session.fpga_type % sectors % sectors << std::endl; // Cleanup image.close(); - flags = (X300_FPGA_READ_FLAGS_CLEANUP | X300_FPGA_READ_FLAGS_ACK); + flags = (X300_FPGA_READ_FLAGS_CLEANUP | X300_FPGA_READ_FLAGS_ACK); pkt_out.sector = pkt_out.index = pkt_out.size = 0; memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES); std::cout << "-- Finalizing image read for verification..." << std::flush; len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in); - if(len == 0){ + if (len == 0) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Timed out waiting for reply from device."); - } - else if((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)){ + } else if ((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)) { std::cout << "failed." << std::endl; throw uhd::runtime_error("Device reported an error during cleanup."); - } - else std::cout << "successful image read." << std::endl; + } else + std::cout << "successful image read." << std::endl; } -static void x300_pcie_load(x300_session_t &session){ - - std::cout << boost::format("\r-- Loading %s FPGA image (this will take 5-10 minutes)...") - % session.fpga_type - << std::flush; +static void x300_pcie_load(x300_session_t& session) +{ + std::cout << boost::format( + "\r-- Loading %s FPGA image (this will take 5-10 minutes)...") + % session.fpga_type + << std::flush; nirio_status status = NiRio_Status_Success; niusrprio::niusrprio_session fpga_session(session.resource, session.rpc_port); - nirio_status_chain(fpga_session.download_bitstream_to_flash(session.filepath), status); + nirio_status_chain( + fpga_session.download_bitstream_to_flash(session.filepath), status); - if(nirio_status_fatal(status)){ + if (nirio_status_fatal(status)) { std::cout << "failed." << std::endl; - niusrprio::nirio_status_to_exception(status, "NI-RIO reported the following error:"); - } - else std::cout << "successful." << std::endl; - std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.") % session.dev_addr.get("product", "")) << std::endl; + niusrprio::nirio_status_to_exception( + status, "NI-RIO reported the following error:"); + } else + std::cout << "successful." << std::endl; + std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.") + % session.dev_addr.get("product", "")) + << std::endl; } -static bool x300_image_loader(const image_loader::image_loader_args_t &image_loader_args){ +static bool x300_image_loader(const image_loader::image_loader_args_t& image_loader_args) +{ // See if any X3x0 with the given args is found device_addrs_t devs = x300_find(image_loader_args.args); - if (devs.size() == 0) return false; + if (devs.size() == 0) + return false; x300_session_t session; x300_setup_session(session, - image_loader_args.args, - image_loader_args.fpga_path, - image_loader_args.out_path); + image_loader_args.args, + image_loader_args.fpga_path, + image_loader_args.out_path); - if(!session.found) return false; + if (!session.found) + return false; std::cout << boost::format("Unit: USRP %s (%s, %s)\nFPGA Image: %s\n") - % session.dev_addr["product"] - % session.dev_addr["serial"] - % session.dev_addr[session.ethernet ? "addr" : "resource"] - % session.filepath; + % session.dev_addr["product"] % session.dev_addr["serial"] + % session.dev_addr[session.ethernet ? "addr" : "resource"] + % session.filepath; // Download the FPGA image to a file - if(image_loader_args.download) { + if (image_loader_args.download) { std::cout << "Attempting to download the FPGA image ..." << std::endl; x300_ethernet_read(session); } - if (not image_loader_args.load_fpga) return true; + if (not image_loader_args.load_fpga) + return true; - if (session.ethernet) x300_ethernet_load(session); - else x300_pcie_load(session); + if (session.ethernet) + x300_ethernet_load(session); + else + x300_pcie_load(session); return true; } -UHD_STATIC_BLOCK(register_x300_image_loader){ - std::string recovery_instructions = "Aborting. Your USRP X-Series device will likely be unusable. Visit\n" - "http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs_jtag\n" - "for details on restoring your device."; +UHD_STATIC_BLOCK(register_x300_image_loader) +{ + std::string recovery_instructions = + "Aborting. Your USRP X-Series device will likely be unusable. Visit\n" + "http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs_jtag\n" + "for details on restoring your device."; image_loader::register_image_loader("x300", x300_image_loader, recovery_instructions); } diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 7d2ce6b28..ed6678761 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -7,29 +7,28 @@ #include "x300_impl.hpp" #include "x300_lvbitx.hpp" -#include "x310_lvbitx.hpp" #include "x300_mb_eeprom_iface.hpp" -#include <uhdlib/usrp/common/apply_corrections.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/log.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/safe_call.hpp> -#include <uhd/usrp/subdev_spec.hpp> +#include "x310_lvbitx.hpp" #include <uhd/transport/if_addrs.hpp> -#include <uhd/transport/udp_zero_copy.hpp> +#include <uhd/transport/nirio/niusrprio_session.h> +#include <uhd/transport/nirio_zero_copy.hpp> #include <uhd/transport/udp_constants.hpp> +#include <uhd/transport/udp_zero_copy.hpp> #include <uhd/transport/zero_copy_recv_offload.hpp> -#include <uhd/transport/nirio_zero_copy.hpp> -#include <uhd/transport/nirio/niusrprio_session.h> -#include <uhd/utils/platform.hpp> #include <uhd/types/sid.hpp> +#include <uhd/usrp/subdev_spec.hpp> +#include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> - +#include <uhd/utils/paths.hpp> +#include <uhd/utils/platform.hpp> +#include <uhd/utils/safe_call.hpp> +#include <uhd/utils/static.hpp> +#include <uhdlib/usrp/common/apply_corrections.hpp> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <boost/make_shared.hpp> -#include <fstream> #include <chrono> +#include <fstream> #include <thread> using namespace uhd; @@ -45,27 +44,28 @@ namespace asio = boost::asio; /****************************************************************************** * Helpers *****************************************************************************/ -static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) { - //Possible options: - //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM - //HA = {0:1G, 1:Aurora} w/ DRAM, XA = {0:10G, 1:Aurora} w/ DRAM +static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) +{ + // Possible options: + // 1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ + // DRAM HA = {0:1G, 1:Aurora} w/ DRAM, XA = {0:10G, 1:Aurora} w/ DRAM std::string option; uint32_t sfp0_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP0_TYPE)); uint32_t sfp1_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP1_TYPE)); - if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_1G_ETH) { + if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_1G_ETH) { option = "1G"; - } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_10G_ETH) { + } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_10G_ETH) { option = "HG"; - } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_10G_ETH) { + } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_10G_ETH) { option = "XG"; - } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_AURORA) { + } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_AURORA) { option = "HA"; - } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_AURORA) { + } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_AURORA) { option = "XA"; } else { - option = "HG"; //Default + option = "HG"; // Default } return option; } @@ -73,153 +73,150 @@ static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) { namespace { - /*! Return the correct motherboard type for a given product ID - * - * Note: In previous versions, we had two different mappings for PCIe and - * Ethernet in case the PIDs would conflict, but they never did and it was - * thus consolidated into one. - */ - x300_impl::x300_mboard_t map_pid_to_mb_type(const uint32_t pid) - { - switch (pid) { - case X300_USRP_PCIE_SSID_ADC_33: - case X300_USRP_PCIE_SSID_ADC_18: - return x300_impl::USRP_X300_MB; - case X310_USRP_PCIE_SSID_ADC_33: - case X310_2940R_40MHz_PCIE_SSID_ADC_33: - case X310_2940R_120MHz_PCIE_SSID_ADC_33: - case X310_2942R_40MHz_PCIE_SSID_ADC_33: - case X310_2942R_120MHz_PCIE_SSID_ADC_33: - case X310_2943R_40MHz_PCIE_SSID_ADC_33: - case X310_2943R_120MHz_PCIE_SSID_ADC_33: - case X310_2944R_40MHz_PCIE_SSID_ADC_33: - case X310_2950R_40MHz_PCIE_SSID_ADC_33: - case X310_2950R_120MHz_PCIE_SSID_ADC_33: - case X310_2952R_40MHz_PCIE_SSID_ADC_33: - case X310_2952R_120MHz_PCIE_SSID_ADC_33: - case X310_2953R_40MHz_PCIE_SSID_ADC_33: - case X310_2953R_120MHz_PCIE_SSID_ADC_33: - case X310_2954R_40MHz_PCIE_SSID_ADC_33: - case X310_USRP_PCIE_SSID_ADC_18: - case X310_2940R_40MHz_PCIE_SSID_ADC_18: - case X310_2940R_120MHz_PCIE_SSID_ADC_18: - case X310_2942R_40MHz_PCIE_SSID_ADC_18: - case X310_2942R_120MHz_PCIE_SSID_ADC_18: - case X310_2943R_40MHz_PCIE_SSID_ADC_18: - case X310_2943R_120MHz_PCIE_SSID_ADC_18: - case X310_2944R_40MHz_PCIE_SSID_ADC_18: - case X310_2945R_PCIE_SSID_ADC_18: - case X310_2950R_40MHz_PCIE_SSID_ADC_18: - case X310_2950R_120MHz_PCIE_SSID_ADC_18: - case X310_2952R_40MHz_PCIE_SSID_ADC_18: - case X310_2952R_120MHz_PCIE_SSID_ADC_18: - case X310_2953R_40MHz_PCIE_SSID_ADC_18: - case X310_2953R_120MHz_PCIE_SSID_ADC_18: - case X310_2954R_40MHz_PCIE_SSID_ADC_18: - case X310_2955R_PCIE_SSID_ADC_18: - return x300_impl::USRP_X310_MB; - case X310_2974_PCIE_SSID_ADC_18: - return x300_impl::USRP_X310_MB_NI_2974; - default: - return x300_impl::UNKNOWN; - } - UHD_THROW_INVALID_CODE_PATH(); +/*! Return the correct motherboard type for a given product ID + * + * Note: In previous versions, we had two different mappings for PCIe and + * Ethernet in case the PIDs would conflict, but they never did and it was + * thus consolidated into one. + */ +x300_impl::x300_mboard_t map_pid_to_mb_type(const uint32_t pid) +{ + switch (pid) { + case X300_USRP_PCIE_SSID_ADC_33: + case X300_USRP_PCIE_SSID_ADC_18: + return x300_impl::USRP_X300_MB; + case X310_USRP_PCIE_SSID_ADC_33: + case X310_2940R_40MHz_PCIE_SSID_ADC_33: + case X310_2940R_120MHz_PCIE_SSID_ADC_33: + case X310_2942R_40MHz_PCIE_SSID_ADC_33: + case X310_2942R_120MHz_PCIE_SSID_ADC_33: + case X310_2943R_40MHz_PCIE_SSID_ADC_33: + case X310_2943R_120MHz_PCIE_SSID_ADC_33: + case X310_2944R_40MHz_PCIE_SSID_ADC_33: + case X310_2950R_40MHz_PCIE_SSID_ADC_33: + case X310_2950R_120MHz_PCIE_SSID_ADC_33: + case X310_2952R_40MHz_PCIE_SSID_ADC_33: + case X310_2952R_120MHz_PCIE_SSID_ADC_33: + case X310_2953R_40MHz_PCIE_SSID_ADC_33: + case X310_2953R_120MHz_PCIE_SSID_ADC_33: + case X310_2954R_40MHz_PCIE_SSID_ADC_33: + case X310_USRP_PCIE_SSID_ADC_18: + case X310_2940R_40MHz_PCIE_SSID_ADC_18: + case X310_2940R_120MHz_PCIE_SSID_ADC_18: + case X310_2942R_40MHz_PCIE_SSID_ADC_18: + case X310_2942R_120MHz_PCIE_SSID_ADC_18: + case X310_2943R_40MHz_PCIE_SSID_ADC_18: + case X310_2943R_120MHz_PCIE_SSID_ADC_18: + case X310_2944R_40MHz_PCIE_SSID_ADC_18: + case X310_2945R_PCIE_SSID_ADC_18: + case X310_2950R_40MHz_PCIE_SSID_ADC_18: + case X310_2950R_120MHz_PCIE_SSID_ADC_18: + case X310_2952R_40MHz_PCIE_SSID_ADC_18: + case X310_2952R_120MHz_PCIE_SSID_ADC_18: + case X310_2953R_40MHz_PCIE_SSID_ADC_18: + case X310_2953R_120MHz_PCIE_SSID_ADC_18: + case X310_2954R_40MHz_PCIE_SSID_ADC_18: + case X310_2955R_PCIE_SSID_ADC_18: + return x300_impl::USRP_X310_MB; + case X310_2974_PCIE_SSID_ADC_18: + return x300_impl::USRP_X310_MB_NI_2974; + default: + return x300_impl::UNKNOWN; } + UHD_THROW_INVALID_CODE_PATH(); +} - /*! Map the motherboard type to a product name - */ - std::string map_mb_type_to_product_name( - const x300_impl::x300_mboard_t mb_type, - const std::string& default_name="") - { - switch (mb_type) { - case x300_impl::USRP_X300_MB: - return "X300"; - case x300_impl::USRP_X310_MB: - return "X310"; - case x300_impl::USRP_X310_MB_NI_2974: - return "NI-2974"; - default: - return default_name; - } +/*! Map the motherboard type to a product name + */ +std::string map_mb_type_to_product_name( + const x300_impl::x300_mboard_t mb_type, const std::string& default_name = "") +{ + switch (mb_type) { + case x300_impl::USRP_X300_MB: + return "X300"; + case x300_impl::USRP_X310_MB: + return "X310"; + case x300_impl::USRP_X310_MB_NI_2974: + return "NI-2974"; + default: + return default_name; } +} -} /* namespace anon */ +} // namespace /*********************************************************************** * Discovery over the udp and pcie transport **********************************************************************/ //@TODO: Refactor the find functions to collapse common code for ethernet and PCIe -static device_addrs_t x300_find_with_addr(const device_addr_t &hint) +static device_addrs_t x300_find_with_addr(const device_addr_t& hint) { - udp_simple::sptr comm = udp_simple::make_broadcast( - hint["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)); + udp_simple::sptr comm = + udp_simple::make_broadcast(hint["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)); - //load request struct + // load request struct x300_fw_comms_t request = x300_fw_comms_t(); - request.flags = uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK); - request.sequence = uhd::htonx<uint32_t>(std::rand()); + request.flags = uhd::htonx<uint32_t>(X300_FW_COMMS_FLAGS_ACK); + request.sequence = uhd::htonx<uint32_t>(std::rand()); - //send request + // send request comm->send(asio::buffer(&request, sizeof(request))); - //loop for replies until timeout + // loop for replies until timeout device_addrs_t addrs; - while (true) - { + while (true) { char buff[X300_FW_COMMS_MTU] = {}; - const size_t nbytes = comm->recv(asio::buffer(buff), 0.050); - if (nbytes == 0) break; - const x300_fw_comms_t *reply = (const x300_fw_comms_t *)buff; - if (request.flags != reply->flags) continue; - if (request.sequence != reply->sequence) continue; + const size_t nbytes = comm->recv(asio::buffer(buff), 0.050); + if (nbytes == 0) + break; + const x300_fw_comms_t* reply = (const x300_fw_comms_t*)buff; + if (request.flags != reply->flags) + continue; + if (request.sequence != reply->sequence) + continue; device_addr_t new_addr; new_addr["type"] = "x300"; new_addr["addr"] = comm->get_recv_addr(); - //Attempt to read the name from the EEPROM and perform filtering. - //This operation can throw due to compatibility mismatch. - try - { + // Attempt to read the name from the EEPROM and perform filtering. + // This operation can throw due to compatibility mismatch. + try { wb_iface::sptr zpu_ctrl = x300_make_ctrl_iface_enet( - udp_simple::make_connected(new_addr["addr"], - BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), + udp_simple::make_connected( + new_addr["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), false /* Suppress timeout errors */ ); new_addr["fpga"] = get_fpga_option(zpu_ctrl); - i2c_core_100_wb32::sptr zpu_i2c = i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); - x300_mb_eeprom_iface::sptr eeprom_iface = x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); - const mboard_eeprom_t mb_eeprom = - x300_impl::get_mb_eeprom(eeprom_iface); - if (mb_eeprom.size() == 0 or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) - { + i2c_core_100_wb32::sptr zpu_i2c = + i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); + x300_mb_eeprom_iface::sptr eeprom_iface = + x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); + const mboard_eeprom_t mb_eeprom = x300_impl::get_mb_eeprom(eeprom_iface); + if (mb_eeprom.size() == 0 + or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) { // Skip device claimed by another process continue; } - new_addr["name"] = mb_eeprom["name"]; - new_addr["serial"] = mb_eeprom["serial"]; + new_addr["name"] = mb_eeprom["name"]; + new_addr["serial"] = mb_eeprom["serial"]; const std::string product_name = map_mb_type_to_product_name( x300_impl::get_mb_type_from_eeprom(mb_eeprom)); if (!product_name.empty()) { new_addr["product"] = product_name; } - } - catch(const std::exception &) - { - //set these values as empty string so the device may still be found - //and the filter's below can still operate on the discovered device - new_addr["name"] = ""; + } catch (const std::exception&) { + // set these values as empty string so the device may still be found + // and the filter's below can still operate on the discovered device + new_addr["name"] = ""; new_addr["serial"] = ""; } - //filter the discovered device below by matching optional keys - if ( - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) and - (not hint.has_key("product") or hint["product"] == new_addr["product"]) - ){ + // filter the discovered device below by matching optional keys + if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) + and (not hint.has_key("product") or hint["product"] == new_addr["product"])) { addrs.push_back(new_addr); } } @@ -228,13 +225,13 @@ static device_addrs_t x300_find_with_addr(const device_addr_t &hint) } -//We need a zpu xport registry to ensure synchronization between the static finder method -//and the instances of the x300_impl class. -typedef uhd::dict< std::string, boost::weak_ptr<wb_iface> > pcie_zpu_iface_registry_t; +// We need a zpu xport registry to ensure synchronization between the static finder method +// and the instances of the x300_impl class. +typedef uhd::dict<std::string, boost::weak_ptr<wb_iface>> pcie_zpu_iface_registry_t; UHD_SINGLETON_FCN(pcie_zpu_iface_registry_t, get_pcie_zpu_iface_registry) static boost::mutex pcie_zpu_iface_registry_mutex; -static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_query) +static device_addrs_t x300_find_pcie(const device_addr_t& hint, bool explicit_query) { std::string rpc_port_name(std::to_string(NIUSRPRIO_DEFAULT_RPC_PORT)); if (hint.has_key("niusrpriorpc_port")) { @@ -244,12 +241,13 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu device_addrs_t addrs; niusrprio_session::device_info_vtr dev_info_vtr; nirio_status status = niusrprio_session::enumerate(rpc_port_name, dev_info_vtr); - if (explicit_query) nirio_status_to_exception(status, "x300_find_pcie: Error enumerating NI-RIO devices."); + if (explicit_query) + nirio_status_to_exception( + status, "x300_find_pcie: Error enumerating NI-RIO devices."); - for(niusrprio_session::device_info &dev_info: dev_info_vtr) - { + for (niusrprio_session::device_info& dev_info : dev_info_vtr) { device_addr_t new_addr; - new_addr["type"] = "x300"; + new_addr["type"] = "x300"; new_addr["resource"] = dev_info.resource_name; std::string resource_d(dev_info.resource_name); boost::to_upper(resource_d); @@ -262,157 +260,154 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu new_addr["product"] = product_name; } - niriok_proxy::sptr kernel_proxy = niriok_proxy::make_and_open(dev_info.interface_path); + niriok_proxy::sptr kernel_proxy = + niriok_proxy::make_and_open(dev_info.interface_path); - //Attempt to read the name from the EEPROM and perform filtering. - //This operation can throw due to compatibility mismatch. - try - { - //This block could throw an exception if the user is switching to using UHD - //after LabVIEW FPGA. In that case, skip reading the name and serial and pick - //a default FPGA flavor. During make, a new image will be loaded and everything - //will be OK + // Attempt to read the name from the EEPROM and perform filtering. + // This operation can throw due to compatibility mismatch. + try { + // This block could throw an exception if the user is switching to using UHD + // after LabVIEW FPGA. In that case, skip reading the name and serial and pick + // a default FPGA flavor. During make, a new image will be loaded and + // everything will be OK wb_iface::sptr zpu_ctrl; - //Hold on to the registry mutex as long as zpu_ctrl is alive - //to prevent any use by different threads while enumerating + // Hold on to the registry mutex as long as zpu_ctrl is alive + // to prevent any use by different threads while enumerating boost::mutex::scoped_lock lock(pcie_zpu_iface_registry_mutex); if (get_pcie_zpu_iface_registry().has_key(resource_d)) { zpu_ctrl = get_pcie_zpu_iface_registry()[resource_d].lock(); - if (!zpu_ctrl) - { + if (!zpu_ctrl) { get_pcie_zpu_iface_registry().pop(resource_d); } } // if the registry didn't have a key OR that key was an orphaned weak_ptr - if (!zpu_ctrl) - { - zpu_ctrl = x300_make_ctrl_iface_pcie(kernel_proxy, false /* suppress timeout errors */); - //We don't put this zpu_ctrl in the registry because we need - //a persistent niriok_proxy associated with the object + if (!zpu_ctrl) { + zpu_ctrl = x300_make_ctrl_iface_pcie( + kernel_proxy, false /* suppress timeout errors */); + // We don't put this zpu_ctrl in the registry because we need + // a persistent niriok_proxy associated with the object } - //Attempt to autodetect the FPGA type + // Attempt to autodetect the FPGA type if (not hint.has_key("fpga")) { new_addr["fpga"] = get_fpga_option(zpu_ctrl); } - i2c_core_100_wb32::sptr zpu_i2c = i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); - x300_mb_eeprom_iface::sptr eeprom_iface = x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); - const mboard_eeprom_t mb_eeprom = - x300_impl::get_mb_eeprom(eeprom_iface); - if (mb_eeprom.size() == 0 or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) - { + i2c_core_100_wb32::sptr zpu_i2c = + i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE); + x300_mb_eeprom_iface::sptr eeprom_iface = + x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c); + const mboard_eeprom_t mb_eeprom = x300_impl::get_mb_eeprom(eeprom_iface); + if (mb_eeprom.size() == 0 + or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER) { // Skip device claimed by another process continue; } - new_addr["name"] = mb_eeprom["name"]; + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = mb_eeprom["serial"]; - } - catch(const std::exception &) - { - //set these values as empty string so the device may still be found - //and the filter's below can still operate on the discovered device + } catch (const std::exception&) { + // set these values as empty string so the device may still be found + // and the filter's below can still operate on the discovered device if (not hint.has_key("fpga")) { new_addr["fpga"] = "HG"; } - new_addr["name"] = ""; + new_addr["name"] = ""; new_addr["serial"] = ""; } - //filter the discovered device below by matching optional keys + // filter the discovered device below by matching optional keys std::string resource_i = hint.has_key("resource") ? hint["resource"] : ""; boost::to_upper(resource_i); - if ( - (not hint.has_key("resource") or resource_i == resource_d) and - (not hint.has_key("name") or hint["name"] == new_addr["name"]) and - (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) and - (not hint.has_key("product") or hint["product"] == new_addr["product"]) - ){ + if ((not hint.has_key("resource") or resource_i == resource_d) + and (not hint.has_key("name") or hint["name"] == new_addr["name"]) + and (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]) + and (not hint.has_key("product") or hint["product"] == new_addr["product"])) { addrs.push_back(new_addr); } } return addrs; } -device_addrs_t x300_find(const device_addr_t &hint_) +device_addrs_t x300_find(const device_addr_t& hint_) { - //handle the multi-device discovery + // handle the multi-device discovery device_addrs_t hints = separate_device_addr(hint_); - if (hints.size() > 1) - { + if (hints.size() > 1) { device_addrs_t found_devices; std::string error_msg; - for(const device_addr_t &hint_i: hints) - { + for (const device_addr_t& hint_i : hints) { device_addrs_t found_devices_i = x300_find(hint_i); - if (found_devices_i.size() != 1) error_msg += str(boost::format( - "Could not resolve device hint \"%s\" to a single device." - ) % hint_i.to_string()); - else found_devices.push_back(found_devices_i[0]); + if (found_devices_i.size() != 1) + error_msg += + str(boost::format( + "Could not resolve device hint \"%s\" to a single device.") + % hint_i.to_string()); + else + found_devices.push_back(found_devices_i[0]); } - if (found_devices.empty()) return device_addrs_t(); - if (not error_msg.empty()) throw uhd::value_error(error_msg); + if (found_devices.empty()) + return device_addrs_t(); + if (not error_msg.empty()) + throw uhd::value_error(error_msg); return device_addrs_t(1, combine_device_addrs(found_devices)); } - //initialize the hint for a single device case + // initialize the hint for a single device case UHD_ASSERT_THROW(hints.size() <= 1); - hints.resize(1); //in case it was empty + hints.resize(1); // in case it was empty device_addr_t hint = hints[0]; device_addrs_t addrs; - if (hint.has_key("type") and hint["type"] != "x300") return addrs; + if (hint.has_key("type") and hint["type"] != "x300") + return addrs; - //use the address given - if (hint.has_key("addr")) - { + // use the address given + if (hint.has_key("addr")) { device_addrs_t reply_addrs; - try - { + try { reply_addrs = x300_find_with_addr(hint); - } - catch(const std::exception &ex) - { - UHD_LOGGER_ERROR("X300") << "X300 Network discovery error " << ex.what() ; - } - catch(...) - { - UHD_LOGGER_ERROR("X300") << "X300 Network discovery unknown error " ; + } catch (const std::exception& ex) { + UHD_LOGGER_ERROR("X300") << "X300 Network discovery error " << ex.what(); + } catch (...) { + UHD_LOGGER_ERROR("X300") << "X300 Network discovery unknown error "; } return reply_addrs; } - if (!hint.has_key("resource")) - { - //otherwise, no address was specified, send a broadcast on each interface - for(const if_addrs_t &if_addrs: get_if_addrs()) - { - //avoid the loopback device - if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue; + if (!hint.has_key("resource")) { + // otherwise, no address was specified, send a broadcast on each interface + for (const if_addrs_t& if_addrs : get_if_addrs()) { + // avoid the loopback device + if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) + continue; - //create a new hint with this broadcast address + // create a new hint with this broadcast address device_addr_t new_hint = hint; - new_hint["addr"] = if_addrs.bcast; + new_hint["addr"] = if_addrs.bcast; - //call discover with the new hint and append results + // call discover with the new hint and append results device_addrs_t new_addrs = x300_find(new_hint); - //if we are looking for a serial, only add the one device with a matching serial + // if we are looking for a serial, only add the one device with a matching + // serial if (hint.has_key("serial")) { - bool found_serial = false; //signal to break out of the interface loop - for (device_addrs_t::iterator new_addr_it=new_addrs.begin(); new_addr_it != new_addrs.end(); new_addr_it++) { + bool found_serial = false; // signal to break out of the interface loop + for (device_addrs_t::iterator new_addr_it = new_addrs.begin(); + new_addr_it != new_addrs.end(); + new_addr_it++) { if ((*new_addr_it)["serial"] == hint["serial"]) { addrs.insert(addrs.begin(), *new_addr_it); found_serial = true; break; } } - if (found_serial) break; + if (found_serial) + break; } else { // Otherwise, add all devices we find addrs.insert(addrs.begin(), new_addrs.begin(), new_addrs.end()); @@ -421,7 +416,8 @@ device_addrs_t x300_find(const device_addr_t &hint_) } device_addrs_t pcie_addrs = x300_find_pcie(hint, hint.has_key("resource")); - if (not pcie_addrs.empty()) addrs.insert(addrs.end(), pcie_addrs.begin(), pcie_addrs.end()); + if (not pcie_addrs.empty()) + addrs.insert(addrs.end(), pcie_addrs.begin(), pcie_addrs.end()); return addrs; } @@ -429,7 +425,7 @@ device_addrs_t x300_find(const device_addr_t &hint_) /*********************************************************************** * Make **********************************************************************/ -static device::sptr x300_make(const device_addr_t &device_addr) +static device::sptr x300_make(const device_addr_t& device_addr) { return device::sptr(new x300_impl(device_addr)); } @@ -439,33 +435,33 @@ UHD_STATIC_BLOCK(register_x300_device) device::register_device(&x300_find, &x300_make, device::USRP); } -static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string &file_name) +static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string& file_name) { UHD_LOGGER_INFO("X300") << "Loading firmware " << file_name; - //load file into memory + // load file into memory std::ifstream fw_file(file_name.c_str()); - uint32_t fw_file_buff[X300_FW_NUM_BYTES/sizeof(uint32_t)]; - fw_file.read((char *)fw_file_buff, sizeof(fw_file_buff)); + uint32_t fw_file_buff[X300_FW_NUM_BYTES / sizeof(uint32_t)]; + fw_file.read((char*)fw_file_buff, sizeof(fw_file_buff)); fw_file.close(); - //Poke the fw words into the WB boot loader + // Poke the fw words into the WB boot loader fw_reg_ctrl->poke32(SR_ADDR(BOOT_LDR_BASE, BL_ADDRESS), 0); - for (size_t i = 0; i < X300_FW_NUM_BYTES; i+=sizeof(uint32_t)) - { - //@TODO: FIXME: Since x300_ctrl_iface acks each write and traps exceptions, the first try for the last word - // written will print an error because it triggers a FW reload and fails to reply. - fw_reg_ctrl->poke32(SR_ADDR(BOOT_LDR_BASE, BL_DATA), uhd::byteswap(fw_file_buff[i/sizeof(uint32_t)])); + for (size_t i = 0; i < X300_FW_NUM_BYTES; i += sizeof(uint32_t)) { + //@TODO: FIXME: Since x300_ctrl_iface acks each write and traps exceptions, the + // first try for the last word + // written will print an error because it triggers a FW reload and + // fails to reply. + fw_reg_ctrl->poke32(SR_ADDR(BOOT_LDR_BASE, BL_DATA), + uhd::byteswap(fw_file_buff[i / sizeof(uint32_t)])); } - //Wait for fimrware to reboot. 3s is an upper bound + // Wait for fimrware to reboot. 3s is an upper bound std::this_thread::sleep_for(std::chrono::milliseconds(3000)); - UHD_LOGGER_INFO("X300") << "Firmware loaded!" ; + UHD_LOGGER_INFO("X300") << "Firmware loaded!"; } -x300_impl::x300_impl(const uhd::device_addr_t &dev_addr) - : device3_impl() - , _sid_framer(0) +x300_impl::x300_impl(const uhd::device_addr_t& dev_addr) : device3_impl(), _sid_framer(0) { UHD_LOGGER_INFO("X300") << "X300 initialization sequence..."; _tree->create<std::string>("/name").set("X-Series Device"); @@ -475,8 +471,7 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr) // Serialize the initialization process if (dev_addr.has_key("serialize_init") or device_args.size() == 1) { - for (size_t i = 0; i < device_args.size(); i++) - { + for (size_t i = 0; i < device_args.size(); i++) { this->setup_mb(i, device_args[i]); } return; @@ -486,26 +481,22 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr) // Initialize groups of USRPs in parallel size_t total_usrps = device_args.size(); size_t num_usrps = 0; - while (num_usrps < total_usrps) - { + while (num_usrps < total_usrps) { size_t init_usrps = std::min(total_usrps - num_usrps, x300::MAX_INIT_THREADS); boost::thread_group setup_threads; - for (size_t i = 0; i < init_usrps; i++) - { + for (size_t i = 0; i < init_usrps; i++) { const size_t index = num_usrps + i; - setup_threads.create_thread([this, index, device_args](){ + setup_threads.create_thread([this, index, device_args]() { this->setup_mb(index, device_args[index]); }); } setup_threads.join_all(); num_usrps += init_usrps; } - } void x300_impl::mboard_members_t::discover_eth( - const mboard_eeprom_t mb_eeprom, - const std::vector<std::string> &ip_addrs) + const mboard_eeprom_t mb_eeprom, const std::vector<std::string>& ip_addrs) { // Clear any previous addresses added eth_conns.clear(); @@ -517,16 +508,19 @@ void x300_impl::mboard_members_t::discover_eth( const std::string key = "ip-addr" + boost::to_string(i); // Show a warning if there exists duplicate addresses in the mboard eeprom - if (std::find(mb_eeprom_addrs.begin(), mb_eeprom_addrs.end(), mb_eeprom[key]) != mb_eeprom_addrs.end()) { - UHD_LOGGER_WARNING("X300") << str(boost::format( - "Duplicate IP address %s found in mboard EEPROM. " - "Device may not function properly. View and reprogram the values " - "using the usrp_burn_mb_eeprom utility.") % mb_eeprom[key]); + if (std::find(mb_eeprom_addrs.begin(), mb_eeprom_addrs.end(), mb_eeprom[key]) + != mb_eeprom_addrs.end()) { + UHD_LOGGER_WARNING("X300") << str( + boost::format( + "Duplicate IP address %s found in mboard EEPROM. " + "Device may not function properly. View and reprogram the values " + "using the usrp_burn_mb_eeprom utility.") + % mb_eeprom[key]); } mb_eeprom_addrs.push_back(mb_eeprom[key]); } - for(const std::string& addr: ip_addrs) { + for (const std::string& addr : ip_addrs) { x300_eth_conn_t conn_iface; conn_iface.addr = addr; conn_iface.type = X300_IFACE_NONE; @@ -537,10 +531,12 @@ void x300_impl::mboard_members_t::discover_eth( if (addr == mb_eeprom_addrs[i]) { // Choose the interface based on the index parity if (i % 2 == 0) { - conn_iface.type = X300_IFACE_ETH0; - conn_iface.link_rate = loaded_fpga_image == "HG" ? x300::MAX_RATE_1GIGE : x300::MAX_RATE_10GIGE; + conn_iface.type = X300_IFACE_ETH0; + conn_iface.link_rate = loaded_fpga_image == "HG" + ? x300::MAX_RATE_1GIGE + : x300::MAX_RATE_10GIGE; } else { - conn_iface.type = X300_IFACE_ETH1; + conn_iface.type = X300_IFACE_ETH1; conn_iface.link_rate = x300::MAX_RATE_10GIGE; } break; @@ -550,45 +546,49 @@ void x300_impl::mboard_members_t::discover_eth( // Check default IP addresses if we couldn't // determine the IP from the mboard eeprom if (conn_iface.type == X300_IFACE_NONE) { - UHD_LOGGER_WARNING("X300") << str(boost::format( - "Address %s not found in mboard EEPROM. Address may be wrong or " - "the EEPROM may be corrupt. Attempting to continue with default " - "IP addresses.") % conn_iface.addr - ); - - if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH0_1G)).to_string()) { - conn_iface.type = X300_IFACE_ETH0; + UHD_LOGGER_WARNING("X300") << str( + boost::format( + "Address %s not found in mboard EEPROM. Address may be wrong or " + "the EEPROM may be corrupt. Attempting to continue with default " + "IP addresses.") + % conn_iface.addr); + + if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH0_1G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH0; conn_iface.link_rate = x300::MAX_RATE_1GIGE; - } else if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH1_1G)).to_string()) { - conn_iface.type = X300_IFACE_ETH1; + } else if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH1_1G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH1; conn_iface.link_rate = x300::MAX_RATE_1GIGE; - } else if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH0_10G)).to_string()) { - conn_iface.type = X300_IFACE_ETH0; + } else if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH0_10G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH0; conn_iface.link_rate = x300::MAX_RATE_10GIGE; - } else if (addr == boost::asio::ip::address_v4( - uint32_t(X300_DEFAULT_IP_ETH1_10G)).to_string()) { - conn_iface.type = X300_IFACE_ETH1; + } else if (addr + == boost::asio::ip::address_v4(uint32_t(X300_DEFAULT_IP_ETH1_10G)) + .to_string()) { + conn_iface.type = X300_IFACE_ETH1; conn_iface.link_rate = x300::MAX_RATE_10GIGE; } else { - throw uhd::assertion_error(str(boost::format( - "X300 Initialization Error: Failed to match address %s with " - "any addresses for the device. Please check the address.") - % conn_iface.addr - )); + throw uhd::assertion_error( + str(boost::format( + "X300 Initialization Error: Failed to match address %s with " + "any addresses for the device. Please check the address.") + % conn_iface.addr)); } } // Save to a vector of connections if (conn_iface.type != X300_IFACE_NONE) { // Check the address before we add it - try - { + try { wb_iface::sptr zpu_ctrl = x300_make_ctrl_iface_enet( - udp_simple::make_connected(conn_iface.addr, - BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), + udp_simple::make_connected( + conn_iface.addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)), false /* Suppress timeout errors */ ); @@ -597,42 +597,40 @@ void x300_impl::mboard_members_t::discover_eth( } // If the address does not work, throw an error - catch(std::exception &) - { - throw uhd::io_error(str(boost::format( - "X300 Initialization Error: Invalid address %s") - % conn_iface.addr)); + catch (std::exception&) { + throw uhd::io_error( + str(boost::format("X300 Initialization Error: Invalid address %s") + % conn_iface.addr)); } eth_conns.push_back(conn_iface); } } if (eth_conns.size() == 0) - throw uhd::assertion_error("X300 Initialization Error: No ethernet interfaces specified."); + throw uhd::assertion_error( + "X300 Initialization Error: No ethernet interfaces specified."); } -void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) +void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t& dev_addr) { - const fs_path mb_path = fs_path("/mboards") / mb_i; - mboard_members_t &mb = _mb[mb_i]; + const fs_path mb_path = fs_path("/mboards") / mb_i; + mboard_members_t& mb = _mb[mb_i]; mb.initialization_done = false; const std::string thread_id( - boost::lexical_cast<std::string>(boost::this_thread::get_id()) - ); + boost::lexical_cast<std::string>(boost::this_thread::get_id())); const std::string thread_msg( - "Thread ID " + thread_id + " for motherboard " - + std::to_string(mb_i) - ); + "Thread ID " + thread_id + " for motherboard " + std::to_string(mb_i)); mb.args.parse(dev_addr); std::vector<std::string> eth_addrs; // Not choosing eth0 based on resource might cause user issues - std::string eth0_addr = dev_addr.has_key("resource") ? dev_addr["resource"] : dev_addr["addr"]; + std::string eth0_addr = dev_addr.has_key("resource") ? dev_addr["resource"] + : dev_addr["addr"]; eth_addrs.push_back(eth0_addr); - mb.next_src_addr = 0; //Host source address for blocks + mb.next_src_addr = 0; // Host source address for blocks mb.next_tx_src_addr = 0; mb.next_rx_src_addr = 0; if (not mb.args.get_second_addr().empty()) { @@ -649,19 +647,18 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) init.addr = eth_addrs[0]; mb.eth_conns.push_back(init); - mb.xport_path = dev_addr.has_key("resource") ? "nirio" : "eth"; + mb.xport_path = dev_addr.has_key("resource") ? "nirio" : "eth"; mb.if_pkt_is_big_endian = mb.xport_path != "nirio"; - if (mb.xport_path == "nirio") - { + if (mb.xport_path == "nirio") { nirio_status status = 0; const std::string rpc_port_name = mb.args.get_niusrprio_rpc_port(); UHD_LOGGER_INFO("X300") << boost::format("Connecting to niusrpriorpc at localhost:%s...") - % rpc_port_name; + % rpc_port_name; - //Instantiate the correct lvbitx object + // Instantiate the correct lvbitx object nifpga_lvbitx::sptr lvbitx; switch (get_mb_type_from_pcie(mb.args.get_resource(), rpc_port_name)) { case USRP_X300_MB: @@ -672,85 +669,95 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) lvbitx.reset(new x310_lvbitx(dev_addr["fpga"])); break; default: - nirio_status_to_exception(status, "Motherboard detection error. Please ensure that you \ + nirio_status_to_exception( + status, "Motherboard detection error. Please ensure that you \ have a valid USRP X3x0, NI USRP-294xR, NI USRP-295xR or NI USRP-2974 device and that all the device \ drivers have loaded successfully."); } - //Load the lvbitx onto the device - UHD_LOGGER_INFO("X300") << boost::format("Using LVBITX bitfile %s...") % lvbitx->get_bitfile_path(); - mb.rio_fpga_interface.reset(new niusrprio_session(dev_addr["resource"], rpc_port_name)); - nirio_status_chain(mb.rio_fpga_interface->open(lvbitx, dev_addr.has_key("download-fpga")), status); + // Load the lvbitx onto the device + UHD_LOGGER_INFO("X300") + << boost::format("Using LVBITX bitfile %s...") % lvbitx->get_bitfile_path(); + mb.rio_fpga_interface.reset( + new niusrprio_session(dev_addr["resource"], rpc_port_name)); + nirio_status_chain( + mb.rio_fpga_interface->open(lvbitx, dev_addr.has_key("download-fpga")), + status); nirio_status_to_exception(status, "x300_impl: Could not initialize RIO session."); - //Tell the quirks object which FIFOs carry TX stream data - const uint32_t tx_data_fifos[2] = {x300::RADIO_DEST_PREFIX_TX, x300::RADIO_DEST_PREFIX_TX + 3}; - mb.rio_fpga_interface->get_kernel_proxy()->get_rio_quirks().register_tx_streams(tx_data_fifos, 2); + // Tell the quirks object which FIFOs carry TX stream data + const uint32_t tx_data_fifos[2] = { + x300::RADIO_DEST_PREFIX_TX, x300::RADIO_DEST_PREFIX_TX + 3}; + mb.rio_fpga_interface->get_kernel_proxy()->get_rio_quirks().register_tx_streams( + tx_data_fifos, 2); _tree->create<size_t>(mb_path / "mtu/recv").set(x300::PCIE_RX_DATA_FRAME_SIZE); _tree->create<size_t>(mb_path / "mtu/send").set(x300::PCIE_TX_DATA_FRAME_SIZE); _tree->create<double>(mb_path / "link_max_rate").set(x300::MAX_RATE_PCIE); } - for(const std::string &key: dev_addr.keys()) - { - if (key.find("recv") != std::string::npos) mb.recv_args[key] = dev_addr[key]; - if (key.find("send") != std::string::npos) mb.send_args[key] = dev_addr[key]; + for (const std::string& key : dev_addr.keys()) { + if (key.find("recv") != std::string::npos) + mb.recv_args[key] = dev_addr[key]; + if (key.find("send") != std::string::npos) + mb.send_args[key] = dev_addr[key]; } - //create basic communication + // create basic communication UHD_LOGGER_DEBUG("X300") << "Setting up basic communication..."; if (mb.xport_path == "nirio") { boost::mutex::scoped_lock lock(pcie_zpu_iface_registry_mutex); if (get_pcie_zpu_iface_registry().has_key(mb.get_pri_eth().addr)) { - throw uhd::assertion_error("Someone else has a ZPU transport to the device open. Internal error!"); + throw uhd::assertion_error( + "Someone else has a ZPU transport to the device open. Internal error!"); } else { - mb.zpu_ctrl = x300_make_ctrl_iface_pcie(mb.rio_fpga_interface->get_kernel_proxy()); - get_pcie_zpu_iface_registry()[mb.get_pri_eth().addr] = boost::weak_ptr<wb_iface>(mb.zpu_ctrl); + mb.zpu_ctrl = + x300_make_ctrl_iface_pcie(mb.rio_fpga_interface->get_kernel_proxy()); + get_pcie_zpu_iface_registry()[mb.get_pri_eth().addr] = + boost::weak_ptr<wb_iface>(mb.zpu_ctrl); } } else { mb.zpu_ctrl = x300_make_ctrl_iface_enet(udp_simple::make_connected( - mb.get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT))); + mb.get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT))); } // Claim device if (not try_to_claim(mb.zpu_ctrl)) { throw uhd::runtime_error("Failed to claim device"); } - mb.claimer_task = uhd::task::make([this, mb](){ - this->claimer_loop(mb.zpu_ctrl); - }, "x300_claimer"); + mb.claimer_task = uhd::task::make( + [this, mb]() { this->claimer_loop(mb.zpu_ctrl); }, "x300_claimer"); - //extract the FW path for the X300 - //and live load fw over ethernet link + // extract the FW path for the X300 + // and live load fw over ethernet link if (mb.args.has_fw_file()) { - const std::string x300_fw_image = - find_image_path(mb.args.get_fw_file()); + const std::string x300_fw_image = find_image_path(mb.args.get_fw_file()); x300_load_fw(mb.zpu_ctrl, x300_fw_image); } - //check compat numbers - //check fpga compat before fw compat because the fw is a subset of the fpga image + // check compat numbers + // check fpga compat before fw compat because the fw is a subset of the fpga image this->check_fpga_compat(mb_path, mb); this->check_fw_compat(mb_path, mb); mb.fw_regmap = boost::make_shared<fw_regmap_t>(); mb.fw_regmap->initialize(*mb.zpu_ctrl.get(), true); - //store which FPGA image is loaded + // store which FPGA image is loaded mb.loaded_fpga_image = get_fpga_option(mb.zpu_ctrl); - //low speed perif access - mb.zpu_spi = spi_core_3000::make(mb.zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_SPI), - SR_ADDR(SET0_BASE, ZPU_RB_SPI)); + // low speed perif access + mb.zpu_spi = spi_core_3000::make( + mb.zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_SPI), SR_ADDR(SET0_BASE, ZPU_RB_SPI)); mb.zpu_i2c = i2c_core_100_wb32::make(mb.zpu_ctrl, I2C1_BASE); - mb.zpu_i2c->set_clock_rate(x300::BUS_CLOCK_RATE/2); + mb.zpu_i2c->set_clock_rate(x300::BUS_CLOCK_RATE / 2); //////////////////////////////////////////////////////////////////// // print network routes mapping //////////////////////////////////////////////////////////////////// /* - const uint32_t routes_addr = mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_ROUTE_MAP_ADDR)); - const uint32_t routes_len = mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_ROUTE_MAP_LEN)); + const uint32_t routes_addr = mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, + X300_FW_SHMEM_ROUTE_MAP_ADDR)); const uint32_t routes_len = + mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_ROUTE_MAP_LEN)); UHD_VAR(routes_len); for (size_t i = 0; i < routes_len; i+=1) { @@ -778,29 +785,28 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) } const mboard_eeprom_t mb_eeprom = get_mb_eeprom(eeprom16); - _tree->create<mboard_eeprom_t>(mb_path / "eeprom") + _tree + ->create<mboard_eeprom_t>(mb_path / "eeprom") // Initialize the property with a current copy of the EEPROM contents .set(mb_eeprom) // Whenever this property is written, update the chip - .add_coerced_subscriber( - [this, eeprom16](const mboard_eeprom_t &mb_eeprom){ - this->set_mb_eeprom(eeprom16, mb_eeprom); - } - ) - ; + .add_coerced_subscriber([this, eeprom16](const mboard_eeprom_t& mb_eeprom) { + this->set_mb_eeprom(eeprom16, mb_eeprom); + }); if (mb.args.get_recover_mb_eeprom()) { - UHD_LOGGER_WARNING("X300") << "UHD is operating in EEPROM Recovery Mode which disables hardware version " - "checks.\nOperating in this mode may cause hardware damage and unstable " - "radio performance!"; + UHD_LOGGER_WARNING("X300") + << "UHD is operating in EEPROM Recovery Mode which disables hardware version " + "checks.\nOperating in this mode may cause hardware damage and unstable " + "radio performance!"; return; } //////////////////////////////////////////////////////////////////// // parse the product number //////////////////////////////////////////////////////////////////// - const std::string product_name = map_mb_type_to_product_name( - get_mb_type_from_eeprom(mb_eeprom), "X300?"); + const std::string product_name = + map_mb_type_to_product_name(get_mb_type_from_eeprom(mb_eeprom), "X300?"); if (product_name == "X300?") { if (not mb.args.get_recover_mb_eeprom()) { throw uhd::runtime_error( @@ -818,7 +824,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) //////////////////////////////////////////////////////////////////// // discover ethernet interfaces, frame sizes, and link rates //////////////////////////////////////////////////////////////////// - if (mb.xport_path == "eth" ) { + if (mb.xport_path == "eth") { double link_max_rate = 0.0; // Discover ethernet interfaces @@ -836,101 +842,104 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) * multiple transmission units - this is why the limits passed into the * 'determine_max_frame_size' function are actually frame sizes. */ frame_size_t req_max_frame_size; - req_max_frame_size.recv_frame_size = (mb.recv_args.has_key("recv_frame_size")) \ - ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) \ - : x300::DATA_FRAME_MAX_SIZE; - req_max_frame_size.send_frame_size = (mb.send_args.has_key("send_frame_size")) \ - ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) \ - : x300::DATA_FRAME_MAX_SIZE; - - #if defined UHD_PLATFORM_LINUX - const std::string mtu_tool("ip link"); - #elif defined UHD_PLATFORM_WIN32 - const std::string mtu_tool("netsh"); - #else - const std::string mtu_tool("ifconfig"); - #endif + req_max_frame_size.recv_frame_size = + (mb.recv_args.has_key("recv_frame_size")) + ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) + : x300::DATA_FRAME_MAX_SIZE; + req_max_frame_size.send_frame_size = + (mb.send_args.has_key("send_frame_size")) + ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) + : x300::DATA_FRAME_MAX_SIZE; + +#if defined UHD_PLATFORM_LINUX + const std::string mtu_tool("ip link"); +#elif defined UHD_PLATFORM_WIN32 + const std::string mtu_tool("netsh"); +#else + const std::string mtu_tool("ifconfig"); +#endif // Detect the frame size on the path to the USRP try { - frame_size_t pri_frame_sizes = determine_max_frame_size( - eth_addrs.at(0), req_max_frame_size - ); + frame_size_t pri_frame_sizes = + determine_max_frame_size(eth_addrs.at(0), req_max_frame_size); _max_frame_sizes = pri_frame_sizes; if (eth_addrs.size() > 1) { - frame_size_t sec_frame_sizes = determine_max_frame_size( - eth_addrs.at(1), req_max_frame_size - ); + frame_size_t sec_frame_sizes = + determine_max_frame_size(eth_addrs.at(1), req_max_frame_size); // Choose the minimum of the max frame sizes // to ensure we don't exceed any one of the links' MTU _max_frame_sizes.recv_frame_size = std::min( - pri_frame_sizes.recv_frame_size, - sec_frame_sizes.recv_frame_size - ); + pri_frame_sizes.recv_frame_size, sec_frame_sizes.recv_frame_size); _max_frame_sizes.send_frame_size = std::min( - pri_frame_sizes.send_frame_size, - sec_frame_sizes.send_frame_size - ); + pri_frame_sizes.send_frame_size, sec_frame_sizes.send_frame_size); } - } catch(std::exception &e) { - UHD_LOGGER_ERROR("X300") << e.what() ; + } catch (std::exception& e) { + UHD_LOGGER_ERROR("X300") << e.what(); } if ((mb.recv_args.has_key("recv_frame_size")) - && (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) { + && (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) { UHD_LOGGER_WARNING("X300") - << boost::format("You requested a receive frame size of (%lu) but your NIC's max frame size is (%lu).") - % req_max_frame_size.recv_frame_size - % _max_frame_sizes.recv_frame_size - << boost::format("Please verify your NIC's MTU setting using '%s' or set the recv_frame_size argument appropriately.") - % mtu_tool - << "UHD will use the auto-detected max frame size for this connection." - ; + << boost::format("You requested a receive frame size of (%lu) but your " + "NIC's max frame size is (%lu).") + % req_max_frame_size.recv_frame_size + % _max_frame_sizes.recv_frame_size + << boost::format("Please verify your NIC's MTU setting using '%s' or set " + "the recv_frame_size argument appropriately.") + % mtu_tool + << "UHD will use the auto-detected max frame size for this connection."; } if ((mb.send_args.has_key("send_frame_size")) - && (req_max_frame_size.send_frame_size > _max_frame_sizes.send_frame_size)) { + && (req_max_frame_size.send_frame_size > _max_frame_sizes.send_frame_size)) { UHD_LOGGER_WARNING("X300") - << boost::format("You requested a send frame size of (%lu) but your NIC's max frame size is (%lu).") - % req_max_frame_size.send_frame_size - % _max_frame_sizes.send_frame_size - << boost::format("Please verify your NIC's MTU setting using '%s' or set the send_frame_size argument appropriately.") - % mtu_tool - << "UHD will use the auto-detected max frame size for this connection." - ; + << boost::format("You requested a send frame size of (%lu) but your " + "NIC's max frame size is (%lu).") + % req_max_frame_size.send_frame_size + % _max_frame_sizes.send_frame_size + << boost::format("Please verify your NIC's MTU setting using '%s' or set " + "the send_frame_size argument appropriately.") + % mtu_tool + << "UHD will use the auto-detected max frame size for this connection."; } // Check frame sizes - for (auto conn : mb.eth_conns) - { + for (auto conn : mb.eth_conns) { link_max_rate += conn.link_rate; - size_t rec_send_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_SEND_SIZE : x300::XGE_DATA_FRAME_SEND_SIZE; - size_t rec_recv_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_RECV_SIZE : x300::XGE_DATA_FRAME_RECV_SIZE; + size_t rec_send_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_SEND_SIZE + : x300::XGE_DATA_FRAME_SEND_SIZE; + size_t rec_recv_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_RECV_SIZE + : x300::XGE_DATA_FRAME_RECV_SIZE; - if (_max_frame_sizes.send_frame_size < rec_send_frame_size) - { + if (_max_frame_sizes.send_frame_size < rec_send_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("For the %s connection, UHD recommends a send frame size of at least %lu for best\nperformance, but your configuration will only allow %lu.") - % conn.addr - % rec_send_frame_size - % _max_frame_sizes.send_frame_size - << "This may negatively impact your maximum achievable sample rate.\nCheck the MTU on the interface and/or the send_frame_size argument." - ; + << boost::format("For the %s connection, UHD recommends a send frame " + "size of at least %lu for best\nperformance, but " + "your configuration will only allow %lu.") + % conn.addr % rec_send_frame_size + % _max_frame_sizes.send_frame_size + << "This may negatively impact your maximum achievable sample " + "rate.\nCheck the MTU on the interface and/or the send_frame_size " + "argument."; } - if (_max_frame_sizes.recv_frame_size < rec_recv_frame_size) - { + if (_max_frame_sizes.recv_frame_size < rec_recv_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("For the %s connection, UHD recommends a receive frame size of at least %lu for best\nperformance, but your configuration will only allow %lu.") - % conn.addr - % rec_recv_frame_size - % _max_frame_sizes.recv_frame_size - << "This may negatively impact your maximum achievable sample rate.\nCheck the MTU on the interface and/or the recv_frame_size argument." - ; + << boost::format("For the %s connection, UHD recommends a receive " + "frame size of at least %lu for best\nperformance, " + "but your configuration will only allow %lu.") + % conn.addr % rec_recv_frame_size + % _max_frame_sizes.recv_frame_size + << "This may negatively impact your maximum achievable sample " + "rate.\nCheck the MTU on the interface and/or the recv_frame_size " + "argument."; } } @@ -943,40 +952,48 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) // read hardware revision and compatibility number //////////////////////////////////////////////////////////////////// mb.hw_rev = 0; - if(mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) { + if (mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) { try { mb.hw_rev = boost::lexical_cast<size_t>(mb_eeprom["revision"]); - } catch(...) { - throw uhd::runtime_error("Revision in EEPROM is invalid! Please reprogram your EEPROM."); + } catch (...) { + throw uhd::runtime_error( + "Revision in EEPROM is invalid! Please reprogram your EEPROM."); } } else { throw uhd::runtime_error("No revision detected. MB EEPROM must be reprogrammed!"); } size_t hw_rev_compat = 0; - if (mb.hw_rev >= 7) { //Revision compat was added with revision 7 - if (mb_eeprom.has_key("revision_compat") and not mb_eeprom["revision_compat"].empty()) { + if (mb.hw_rev >= 7) { // Revision compat was added with revision 7 + if (mb_eeprom.has_key("revision_compat") + and not mb_eeprom["revision_compat"].empty()) { try { hw_rev_compat = boost::lexical_cast<size_t>(mb_eeprom["revision_compat"]); - } catch(...) { - throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please reprogram your EEPROM."); + } catch (...) { + throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please " + "reprogram your EEPROM."); } } else { - throw uhd::runtime_error("No revision compat detected. MB EEPROM must be reprogrammed!"); + throw uhd::runtime_error( + "No revision compat detected. MB EEPROM must be reprogrammed!"); } } else { - //For older HW just assume that revision_compat = revision + // For older HW just assume that revision_compat = revision hw_rev_compat = mb.hw_rev; } if (hw_rev_compat > X300_REVISION_COMPAT) { - throw uhd::runtime_error(str(boost::format( - "Hardware is too new for this software. Please upgrade to a driver that supports hardware revision %d.") - % mb.hw_rev)); - } else if (mb.hw_rev < X300_REVISION_MIN) { //Compare min against the revision (and not compat) to give us more leeway for partial support for a compat - throw uhd::runtime_error(str(boost::format( - "Software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.") - % mb.hw_rev)); + throw uhd::runtime_error( + str(boost::format("Hardware is too new for this software. Please upgrade to " + "a driver that supports hardware revision %d.") + % mb.hw_rev)); + } else if (mb.hw_rev < X300_REVISION_MIN) { // Compare min against the revision (and + // not compat) to give us more leeway for + // partial support for a compat + throw uhd::runtime_error( + str(boost::format("Software is too new for this hardware. Please downgrade " + "to a driver that supports hardware revision %d.") + % mb.hw_rev)); } //////////////////////////////////////////////////////////////////// @@ -984,63 +1001,55 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) //////////////////////////////////////////////////////////////////// UHD_LOGGER_DEBUG("X300") << "Setting up RF frontend clocking..."; - //Initialize clock control registers. NOTE: This does not configure the LMK yet. + // Initialize clock control registers. NOTE: This does not configure the LMK yet. mb.clock = x300_clock_ctrl::make(mb.zpu_spi, 1 /*slaveno*/, mb.hw_rev, mb.args.get_master_clock_rate(), mb.args.get_dboard_clock_rate(), - mb.args.get_system_ref_rate() - ); + mb.args.get_system_ref_rate()); mb.fw_regmap->ref_freq_reg.write( - fw_regmap_t::ref_freq_reg_t::REF_FREQ, - uint32_t(mb.args.get_system_ref_rate()) - ); + fw_regmap_t::ref_freq_reg_t::REF_FREQ, uint32_t(mb.args.get_system_ref_rate())); - //Initialize clock source to use internal reference and generate - //a valid radio clock. This may change after configuration is done. - //This will configure the LMK and wait for lock + // Initialize clock source to use internal reference and generate + // a valid radio clock. This may change after configuration is done. + // This will configure the LMK and wait for lock update_clock_source(mb, mb.args.get_clock_source()); //////////////////////////////////////////////////////////////////// // create clock properties //////////////////////////////////////////////////////////////////// - _tree->create<double>(mb_path / "master_clock_rate") - .set_publisher([mb](){ return mb.clock->get_master_clock_rate(); }) - ; + _tree->create<double>(mb_path / "master_clock_rate").set_publisher([mb]() { + return mb.clock->get_master_clock_rate(); + }); - UHD_LOGGER_INFO("X300") - << "Radio 1x clock: " << (mb.clock->get_master_clock_rate()/1e6) - << " MHz"; + UHD_LOGGER_INFO("X300") << "Radio 1x clock: " + << (mb.clock->get_master_clock_rate() / 1e6) << " MHz"; //////////////////////////////////////////////////////////////////// // Create the GPSDO control //////////////////////////////////////////////////////////////////// static const uint32_t dont_look_for_gpsdo = 0x1234abcdul; - //otherwise if not disabled, look for the internal GPSDO - if (mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS)) != dont_look_for_gpsdo) - { + // otherwise if not disabled, look for the internal GPSDO + if (mb.zpu_ctrl->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS)) + != dont_look_for_gpsdo) { UHD_LOG_DEBUG("X300", "Detecting internal GPSDO...."); try { // gps_ctrl will print its own log statements if a GPSDO was found mb.gps = gps_ctrl::make(x300_make_uart_iface(mb.zpu_ctrl)); - } - catch(std::exception &e) { + } catch (std::exception& e) { UHD_LOGGER_ERROR("X300") << "An error occurred making GPSDO control: " << e.what(); } if (mb.gps and mb.gps->gps_detected()) { - for(const std::string& name : mb.gps->get_sensors()) { + for (const std::string& name : mb.gps->get_sensors()) { _tree->create<sensor_value_t>(mb_path / "sensors" / name) - .set_publisher([&mb, name](){ - return mb.gps->get_sensor(name); - }) - ; + .set_publisher([&mb, name]() { return mb.gps->get_sensor(name); }); } - } - else { - mb.zpu_ctrl->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS), dont_look_for_gpsdo); + } else { + mb.zpu_ctrl->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_GPSDO_STATUS), + dont_look_for_gpsdo); } } @@ -1049,97 +1058,88 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) //////////////////////////////////////////////////////////////////// _tree->create<std::string>(mb_path / "time_source" / "value") .set(mb.args.get_time_source()) - .add_coerced_subscriber([this, &mb](const std::string& time_source){ + .add_coerced_subscriber([this, &mb](const std::string& time_source) { this->update_time_source(mb, time_source); - }) - ; - static const std::vector<std::string> time_sources = - {"internal", "external", "gpsdo"}; + }); + static const std::vector<std::string> time_sources = { + "internal", "external", "gpsdo"}; _tree->create<std::vector<std::string>>(mb_path / "time_source" / "options") .set(time_sources); - //setup the time output, default to ON + // setup the time output, default to ON _tree->create<bool>(mb_path / "time_source" / "output") - .add_coerced_subscriber([this, &mb](const bool time_output){ + .add_coerced_subscriber([this, &mb](const bool time_output) { this->set_time_source_out(mb, time_output); }) - .set(true) - ; + .set(true); //////////////////////////////////////////////////////////////////// // setup clock sources and properties //////////////////////////////////////////////////////////////////// _tree->create<std::string>(mb_path / "clock_source" / "value") .set(mb.args.get_clock_source()) - .add_coerced_subscriber([this, &mb](const std::string& clock_source){ + .add_coerced_subscriber([this, &mb](const std::string& clock_source) { this->update_clock_source(mb, clock_source); - }) - ; - static const std::vector<std::string> clock_source_options = - {"internal", "external", "gpsdo"}; + }); + static const std::vector<std::string> clock_source_options = { + "internal", "external", "gpsdo"}; _tree->create<std::vector<std::string>>(mb_path / "clock_source" / "options") .set(clock_source_options); - //setup external reference options. default to 10 MHz input reference + // setup external reference options. default to 10 MHz input reference _tree->create<std::string>(mb_path / "clock_source" / "external"); - _tree->create<std::vector<double>>(mb_path / "clock_source" / "external" / "freq" / "options") + _tree + ->create<std::vector<double>>( + mb_path / "clock_source" / "external" / "freq" / "options") .set(x300::EXTERNAL_FREQ_OPTIONS); _tree->create<double>(mb_path / "clock_source" / "external" / "value") .set(mb.clock->get_sysref_clock_rate()); // FIXME the external clock source settings need to be more robust - //setup the clock output, default to ON + // setup the clock output, default to ON _tree->create<bool>(mb_path / "clock_source" / "output") - .add_coerced_subscriber([&mb](const bool clock_output){ - mb.clock->set_ref_out(clock_output); - }) - ; + .add_coerced_subscriber( + [&mb](const bool clock_output) { mb.clock->set_ref_out(clock_output); }); // Initialize tick rate (must be done before setting time) // Note: The master tick rate can't be changed at runtime! const double master_clock_rate = mb.clock->get_master_clock_rate(); _tree->create<double>(mb_path / "tick_rate") - .set_coercer([master_clock_rate](const double rate){ + .set_coercer([master_clock_rate](const double rate) { // The contract of multi_usrp::set_master_clock_rate() is to coerce // and not throw, so we'll follow that behaviour here. if (!uhd::math::frequencies_are_equal(rate, master_clock_rate)) { - UHD_LOGGER_WARNING("X300") << - "Cannot update master clock rate! X300 Series does not " - "allow changing the clock rate during runtime." - ; + UHD_LOGGER_WARNING("X300") + << "Cannot update master clock rate! X300 Series does not " + "allow changing the clock rate during runtime."; } return master_clock_rate; }) - .add_coerced_subscriber([this](const double rate){ - this->update_tx_streamers(rate); - }) - .add_coerced_subscriber([this](const double rate){ - this->update_rx_streamers(rate); - }) - .set(master_clock_rate) - ; + .add_coerced_subscriber( + [this](const double rate) { this->update_tx_streamers(rate); }) + .add_coerced_subscriber( + [this](const double rate) { this->update_rx_streamers(rate); }) + .set(master_clock_rate); //////////////////////////////////////////////////////////////////// // and do the misc mboard sensors //////////////////////////////////////////////////////////////////// _tree->create<sensor_value_t>(mb_path / "sensors" / "ref_locked") - .set_publisher([this, &mb](){ return this->get_ref_locked(mb); }); + .set_publisher([this, &mb]() { return this->get_ref_locked(mb); }); //////////////// RFNOC ///////////////// const size_t n_rfnoc_blocks = mb.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_NUM_CE)); - enumerate_rfnoc_blocks( - mb_i, + enumerate_rfnoc_blocks(mb_i, n_rfnoc_blocks, x300::XB_DST_PCI + 1, /* base port */ uhd::sid_t(x300::SRC_ADDR0, 0, x300::DST_ADDR + mb_i, 0), - dev_addr - ); + dev_addr); //////////////// RFNOC ///////////////// // If we have a radio, we must configure its codec control: const std::string radio_blockid_hint = str(boost::format("%d/Radio") % mb_i); std::vector<rfnoc::block_id_t> radio_ids = - find_blocks<rfnoc::x300_radio_ctrl_impl>(radio_blockid_hint); + find_blocks<rfnoc::x300_radio_ctrl_impl>(radio_blockid_hint); if (not radio_ids.empty()) { if (radio_ids.size() > 2) { UHD_LOGGER_WARNING("X300") @@ -1147,33 +1147,31 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) radio_ids.resize(2); } - for(const rfnoc::block_id_t &id: radio_ids) { - rfnoc::x300_radio_ctrl_impl::sptr radio(get_block_ctrl<rfnoc::x300_radio_ctrl_impl>(id)); + for (const rfnoc::block_id_t& id : radio_ids) { + rfnoc::x300_radio_ctrl_impl::sptr radio( + get_block_ctrl<rfnoc::x300_radio_ctrl_impl>(id)); mb.radios.push_back(radio); - radio->setup_radio( - mb.zpu_i2c, - mb.clock, - mb.args.get_ignore_cal_file(), - mb.args.get_self_cal_adc_delay() - ); + radio->setup_radio(mb.zpu_i2c, + mb.clock, + mb.args.get_ignore_cal_file(), + mb.args.get_self_cal_adc_delay()); } //////////////////////////////////////////////////////////////////// // ADC test and cal //////////////////////////////////////////////////////////////////// if (mb.args.get_self_cal_adc_delay()) { - rfnoc::x300_radio_ctrl_impl::self_cal_adc_xfer_delay( - mb.radios, mb.clock, - [this, &mb](const double timeout){ - return this->wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout); + rfnoc::x300_radio_ctrl_impl::self_cal_adc_xfer_delay(mb.radios, + mb.clock, + [this, &mb](const double timeout) { + return this->wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout); }, true /* Apply ADC delay */); } if (mb.args.get_ext_adc_self_test()) { rfnoc::x300_radio_ctrl_impl::extended_adc_test( - mb.radios, - mb.args.get_ext_adc_self_test_duration() - ); + mb.radios, mb.args.get_ext_adc_self_test_duration()); } else { for (size_t i = 0; i < mb.radios.size(); i++) { mb.radios.at(i)->self_test_adc(); @@ -1188,8 +1186,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) } } else { - UHD_LOGGER_INFO("X300") - << "No Radio Block found. Assuming radio-less operation."; + UHD_LOGGER_INFO("X300") << "No Radio Block found. Assuming radio-less operation."; } /* end of radio block(s) initialization */ mb.initialization_done = true; @@ -1197,30 +1194,27 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) x300_impl::~x300_impl(void) { - try - { - for(mboard_members_t &mb: _mb) - { - //kill the claimer task and unclaim the device + try { + for (mboard_members_t& mb : _mb) { + // kill the claimer task and unclaim the device mb.claimer_task.reset(); - { //Critical section + { // Critical section boost::mutex::scoped_lock lock(pcie_zpu_iface_registry_mutex); release(mb.zpu_ctrl); - //If the process is killed, the entire registry will disappear so we - //don't need to worry about unclean shutdowns here. + // If the process is killed, the entire registry will disappear so we + // don't need to worry about unclean shutdowns here. if (get_pcie_zpu_iface_registry().has_key(mb.get_pri_eth().addr)) { get_pcie_zpu_iface_registry().pop(mb.get_pri_eth().addr); } } } - } - catch(...) - { + } catch (...) { UHD_SAFE_CALL(throw;) } } -uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan(const uhd::sid_t &tx_sid, const xport_type_t xport_type) +uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan( + const uhd::sid_t& tx_sid, const xport_type_t xport_type) { static const uint32_t CTRL_CHANNEL = 0; static const uint32_t ASYNC_MSG_CHANNEL = 1; @@ -1236,28 +1230,29 @@ uint32_t x300_impl::mboard_members_t::allocate_pcie_dma_chan(const uhd::sid_t &t if (_dma_chan_pool.count(raw_sid) == 0) { size_t channel = _dma_chan_pool.size() + FIRST_DATA_CHANNEL; if (channel > x300::PCIE_MAX_CHANNELS) { - throw uhd::runtime_error("Trying to allocate more DMA channels than are available"); + throw uhd::runtime_error( + "Trying to allocate more DMA channels than are available"); } _dma_chan_pool[raw_sid] = channel; UHD_LOGGER_DEBUG("X300") - << "Assigning PCIe DMA channel " << _dma_chan_pool[raw_sid] - << " to SID " << tx_sid.to_pp_string_hex(); + << "Assigning PCIe DMA channel " << _dma_chan_pool[raw_sid] << " to SID " + << tx_sid.to_pp_string_hex(); } return _dma_chan_pool[raw_sid]; } } -static uint32_t extract_sid_from_pkt(void* pkt, size_t) { +static uint32_t extract_sid_from_pkt(void* pkt, size_t) +{ return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1])).get_dst(); } -static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport -( +static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport( uhd::niusrprio::niusrprio_session::sptr rio_fpga_interface, uint32_t dma_channel_num, - size_t max_muxed_ports -) { + size_t max_muxed_ports) +{ zero_copy_xport_params buff_args; buff_args.send_frame_size = x300::PCIE_MSG_FRAME_SIZE; buff_args.recv_frame_size = x300::PCIE_MSG_FRAME_SIZE; @@ -1265,77 +1260,70 @@ static uhd::transport::muxed_zero_copy_if::sptr make_muxed_pcie_msg_xport buff_args.num_recv_frames = x300::PCIE_MSG_NUM_FRAMES * max_muxed_ports; zero_copy_if::sptr base_xport = nirio_zero_copy::make( - rio_fpga_interface, dma_channel_num, - buff_args, uhd::device_addr_t()); + rio_fpga_interface, dma_channel_num, buff_args, uhd::device_addr_t()); return muxed_zero_copy_if::make(base_xport, extract_sid_from_pkt, max_muxed_ports); } -uhd::both_xports_t x300_impl::make_transport( - const uhd::sid_t &address, +uhd::both_xports_t x300_impl::make_transport(const uhd::sid_t& address, const xport_type_t xport_type, - const uhd::device_addr_t& args -) { - const size_t mb_index = address.get_dst_addr() - x300::DST_ADDR; - mboard_members_t &mb = _mb[mb_index]; - const uhd::device_addr_t& xport_args = (xport_type == CTRL) ? uhd::device_addr_t() : args; + const uhd::device_addr_t& args) +{ + const size_t mb_index = address.get_dst_addr() - x300::DST_ADDR; + mboard_members_t& mb = _mb[mb_index]; + const uhd::device_addr_t& xport_args = (xport_type == CTRL) ? uhd::device_addr_t() + : args; zero_copy_xport_params default_buff_args; both_xports_t xports; xports.endianness = mb.if_pkt_is_big_endian ? ENDIANNESS_BIG : ENDIANNESS_LITTLE; if (mb.xport_path == "nirio") { - xports.send_sid = this->allocate_sid(mb, address, x300::SRC_ADDR0, x300::XB_DST_PCI); + xports.send_sid = + this->allocate_sid(mb, address, x300::SRC_ADDR0, x300::XB_DST_PCI); xports.recv_sid = xports.send_sid.reversed(); uint32_t dma_channel_num = mb.allocate_pcie_dma_chan(xports.send_sid, xport_type); if (xport_type == CTRL) { - //Transport for control stream + // Transport for control stream if (not mb.ctrl_dma_xport) { - //One underlying DMA channel will handle - //all control traffic - mb.ctrl_dma_xport = make_muxed_pcie_msg_xport( - mb.rio_fpga_interface, + // One underlying DMA channel will handle + // all control traffic + mb.ctrl_dma_xport = make_muxed_pcie_msg_xport(mb.rio_fpga_interface, dma_channel_num, x300::PCIE_MAX_MUXED_CTRL_XPORTS); } - //Create a virtual control transport + // Create a virtual control transport xports.recv = mb.ctrl_dma_xport->make_stream(xports.recv_sid.get_dst()); } else if (xport_type == ASYNC_MSG) { - //Transport for async message stream + // Transport for async message stream if (not mb.async_msg_dma_xport) { - //One underlying DMA channel will handle - //all async message traffic - mb.async_msg_dma_xport = make_muxed_pcie_msg_xport( - mb.rio_fpga_interface, + // One underlying DMA channel will handle + // all async message traffic + mb.async_msg_dma_xport = make_muxed_pcie_msg_xport(mb.rio_fpga_interface, dma_channel_num, x300::PCIE_MAX_MUXED_ASYNC_XPORTS); } - //Create a virtual async message transport + // Create a virtual async message transport xports.recv = mb.async_msg_dma_xport->make_stream(xports.recv_sid.get_dst()); } else { - //Transport for data stream - default_buff_args.send_frame_size = - (xport_type == TX_DATA) - ? x300::PCIE_TX_DATA_FRAME_SIZE - : x300::PCIE_MSG_FRAME_SIZE; - - default_buff_args.recv_frame_size = - (xport_type == RX_DATA) - ? x300::PCIE_RX_DATA_FRAME_SIZE - : x300::PCIE_MSG_FRAME_SIZE; - - default_buff_args.num_send_frames = - (xport_type == TX_DATA) - ? x300::PCIE_TX_DATA_NUM_FRAMES - : x300::PCIE_MSG_NUM_FRAMES; + // Transport for data stream + default_buff_args.send_frame_size = (xport_type == TX_DATA) + ? x300::PCIE_TX_DATA_FRAME_SIZE + : x300::PCIE_MSG_FRAME_SIZE; - default_buff_args.num_recv_frames = - (xport_type == RX_DATA) - ? x300::PCIE_RX_DATA_NUM_FRAMES - : x300::PCIE_MSG_NUM_FRAMES; + default_buff_args.recv_frame_size = (xport_type == RX_DATA) + ? x300::PCIE_RX_DATA_FRAME_SIZE + : x300::PCIE_MSG_FRAME_SIZE; + + default_buff_args.num_send_frames = (xport_type == TX_DATA) + ? x300::PCIE_TX_DATA_NUM_FRAMES + : x300::PCIE_MSG_NUM_FRAMES; + + default_buff_args.num_recv_frames = (xport_type == RX_DATA) + ? x300::PCIE_RX_DATA_NUM_FRAMES + : x300::PCIE_MSG_NUM_FRAMES; xports.recv = nirio_zero_copy::make( - mb.rio_fpga_interface, dma_channel_num, - default_buff_args, xport_args); + mb.rio_fpga_interface, dma_channel_num, default_buff_args, xport_args); } xports.send = xports.recv; @@ -1344,23 +1332,27 @@ uhd::both_xports_t x300_impl::make_transport( // - Upper 16 bits: Destination address (e.g. 0.0) // - Lower 16 bits: DMA channel uint32_t router_config_word = (xports.recv_sid.get_dst() << 16) | dma_channel_num; - mb.rio_fpga_interface->get_kernel_proxy()->poke(PCIE_ROUTER_REG(0), router_config_word); + mb.rio_fpga_interface->get_kernel_proxy()->poke( + PCIE_ROUTER_REG(0), router_config_word); - //For the nirio transport, buffer size is depends on the frame size and num frames - xports.recv_buff_size = xports.recv->get_num_recv_frames() * xports.recv->get_recv_frame_size(); - xports.send_buff_size = xports.send->get_num_send_frames() * xports.send->get_send_frame_size(); + // For the nirio transport, buffer size is depends on the frame size and num + // frames + xports.recv_buff_size = + xports.recv->get_num_recv_frames() * xports.recv->get_recv_frame_size(); + xports.send_buff_size = + xports.send->get_num_send_frames() * xports.send->get_send_frame_size(); } else if (mb.xport_path == "eth") { // Decide on the IP/Interface pair based on the endpoint index - size_t &next_src_addr = - xport_type == TX_DATA ? mb.next_tx_src_addr : - xport_type == RX_DATA ? mb.next_rx_src_addr : - mb.next_src_addr; - x300_eth_conn_t conn = mb.eth_conns[next_src_addr]; - const uint32_t xbar_src_addr = - next_src_addr==0 ? x300::SRC_ADDR0 : x300::SRC_ADDR1; - const uint32_t xbar_src_dst = - conn.type==X300_IFACE_ETH0 ? x300::XB_DST_E0 : x300::XB_DST_E1; + size_t& next_src_addr = xport_type == TX_DATA + ? mb.next_tx_src_addr + : xport_type == RX_DATA ? mb.next_rx_src_addr + : mb.next_src_addr; + x300_eth_conn_t conn = mb.eth_conns[next_src_addr]; + const uint32_t xbar_src_addr = next_src_addr == 0 ? x300::SRC_ADDR0 + : x300::SRC_ADDR1; + const uint32_t xbar_src_dst = conn.type == X300_IFACE_ETH0 ? x300::XB_DST_E0 + : x300::XB_DST_E1; // Do not increment src addr for tx_data by default, using dual ethernet // with the DMA FIFO causes sequence errors to DMA FIFO bandwidth @@ -1373,119 +1365,125 @@ uhd::both_xports_t x300_impl::make_transport( xports.recv_sid = xports.send_sid.reversed(); // Set size and number of frames - size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size; - size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size; - default_buff_args.send_frame_size = std::min(system_max_send_frame_size, x300::ETH_MSG_FRAME_SIZE); - default_buff_args.recv_frame_size = std::min(system_max_recv_frame_size, x300::ETH_MSG_FRAME_SIZE); + size_t system_max_send_frame_size = (size_t)_max_frame_sizes.send_frame_size; + size_t system_max_recv_frame_size = (size_t)_max_frame_sizes.recv_frame_size; + default_buff_args.send_frame_size = + std::min(system_max_send_frame_size, x300::ETH_MSG_FRAME_SIZE); + default_buff_args.recv_frame_size = + std::min(system_max_recv_frame_size, x300::ETH_MSG_FRAME_SIZE); default_buff_args.send_buff_size = conn.link_rate / 50; // 20ms - default_buff_args.recv_buff_size = std::max(conn.link_rate / 50, x300::ETH_MSG_NUM_FRAMES * x300::ETH_MSG_FRAME_SIZE); // enough to hold greater of 20ms or number of msg frames - if (xport_type == TX_DATA) - { - size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_SEND_SIZE : x300::XGE_DATA_FRAME_SEND_SIZE; - default_buff_args.send_frame_size = args.cast<size_t>("send_frame_size", std::min(default_frame_size, system_max_send_frame_size)); - if (default_buff_args.send_frame_size > system_max_send_frame_size) - { + default_buff_args.recv_buff_size = std::max(conn.link_rate / 50, + x300::ETH_MSG_NUM_FRAMES + * x300::ETH_MSG_FRAME_SIZE); // enough to hold greater of 20ms or number + // of msg frames + if (xport_type == TX_DATA) { + size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_SEND_SIZE + : x300::XGE_DATA_FRAME_SEND_SIZE; + default_buff_args.send_frame_size = args.cast<size_t>("send_frame_size", + std::min(default_frame_size, system_max_send_frame_size)); + if (default_buff_args.send_frame_size > system_max_send_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("Requested send_frame_size of %d exceeds the maximum allowed on the %s connection. Using %d.") - % default_buff_args.send_frame_size - % conn.addr - % system_max_send_frame_size - ; + << boost::format("Requested send_frame_size of %d exceeds the " + "maximum allowed on the %s connection. Using %d.") + % default_buff_args.send_frame_size % conn.addr + % system_max_send_frame_size; default_buff_args.send_frame_size = system_max_send_frame_size; } - } - else if (xport_type == RX_DATA) - { - size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE ? x300::GE_DATA_FRAME_RECV_SIZE : x300::XGE_DATA_FRAME_RECV_SIZE; - default_buff_args.recv_frame_size = args.cast<size_t>("recv_frame_size", std::min(default_frame_size, system_max_recv_frame_size)); - if (default_buff_args.recv_frame_size > system_max_recv_frame_size) - { + } else if (xport_type == RX_DATA) { + size_t default_frame_size = conn.link_rate == x300::MAX_RATE_1GIGE + ? x300::GE_DATA_FRAME_RECV_SIZE + : x300::XGE_DATA_FRAME_RECV_SIZE; + default_buff_args.recv_frame_size = args.cast<size_t>("recv_frame_size", + std::min(default_frame_size, system_max_recv_frame_size)); + if (default_buff_args.recv_frame_size > system_max_recv_frame_size) { UHD_LOGGER_WARNING("X300") - << boost::format("Requested recv_frame_size of %d exceeds the maximum allowed on the %s connection. Using %d.") - % default_buff_args.recv_frame_size - % conn.addr - % system_max_recv_frame_size - ; + << boost::format("Requested recv_frame_size of %d exceeds the " + "maximum allowed on the %s connection. Using %d.") + % default_buff_args.recv_frame_size % conn.addr + % system_max_recv_frame_size; default_buff_args.recv_frame_size = system_max_recv_frame_size; } - default_buff_args.num_recv_frames = 2; // set some buffers so the offload thread actually offloads the socket I/O + default_buff_args.num_recv_frames = + 2; // set some buffers so the offload thread actually offloads the socket + // I/O } - //make a new transport - fpga has no idea how to talk to us on this yet + // make a new transport - fpga has no idea how to talk to us on this yet udp_zero_copy::buff_params buff_params; - xports.recv = udp_zero_copy::make( - conn.addr, - BOOST_STRINGIZE(X300_VITA_UDP_PORT), - default_buff_args, - buff_params, - xport_args); + xports.recv = udp_zero_copy::make(conn.addr, + BOOST_STRINGIZE(X300_VITA_UDP_PORT), + default_buff_args, + buff_params, + xport_args); // Create a threaded transport for the receive chain only // Note that this shouldn't affect PCIe if (xport_type == RX_DATA) { xports.recv = zero_copy_recv_offload::make( - xports.recv, - x300::RECV_OFFLOAD_BUFFER_TIMEOUT - ); + xports.recv, x300::RECV_OFFLOAD_BUFFER_TIMEOUT); } xports.send = xports.recv; - //For the UDP transport the buffer size is the size of the socket buffer - //in the kernel + // For the UDP transport the buffer size is the size of the socket buffer + // in the kernel xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; - //clear the ethernet dispatcher's udp port - //NOT clearing this, the dispatcher is now intelligent + // clear the ethernet dispatcher's udp port + // NOT clearing this, the dispatcher is now intelligent //_zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0+8+3)), 0); - //send a mini packet with SID into the ZPU - //ZPU will reprogram the ethernet framer - UHD_LOGGER_DEBUG("X300") << "programming packet for new xport on " - << conn.addr << " sid " << xports.send_sid ; - //YES, get a __send__ buffer from the __recv__ socket + // send a mini packet with SID into the ZPU + // ZPU will reprogram the ethernet framer + UHD_LOGGER_DEBUG("X300") << "programming packet for new xport on " << conn.addr + << " sid " << xports.send_sid; + // YES, get a __send__ buffer from the __recv__ socket //-- this is the only way to program the framer for recv: managed_send_buffer::sptr buff = xports.recv->get_send_buff(); - buff->cast<uint32_t *>()[0] = 0; //eth dispatch looks for != 0 - buff->cast<uint32_t *>()[1] = uhd::htonx(xports.send_sid.get()); + buff->cast<uint32_t*>()[0] = 0; // eth dispatch looks for != 0 + buff->cast<uint32_t*>()[1] = uhd::htonx(xports.send_sid.get()); buff->commit(8); buff.reset(); - //reprogram the ethernet dispatcher's udp port (should be safe to always set) - UHD_LOGGER_TRACE("X300") - << "reprogram the ethernet dispatcher's udp port" ; - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0+8+3)), X300_VITA_UDP_PORT); - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT1+8+3)), X300_VITA_UDP_PORT); + // reprogram the ethernet dispatcher's udp port (should be safe to always set) + UHD_LOGGER_TRACE("X300") << "reprogram the ethernet dispatcher's udp port"; + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0 + 8 + 3)), X300_VITA_UDP_PORT); + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT1 + 8 + 3)), X300_VITA_UDP_PORT); - //Do a peek to an arbitrary address to guarantee that the - //ethernet framer has been programmed before we return. + // Do a peek to an arbitrary address to guarantee that the + // ethernet framer has been programmed before we return. mb.zpu_ctrl->peek32(0); } return xports; } -uhd::sid_t x300_impl::allocate_sid( - mboard_members_t &mb, - const uhd::sid_t &address, - const uint32_t src_addr, - const uint32_t src_dst -) { +uhd::sid_t x300_impl::allocate_sid(mboard_members_t& mb, + const uhd::sid_t& address, + const uint32_t src_addr, + const uint32_t src_dst) +{ uhd::sid_t sid = address; sid.set_src_addr(src_addr); - sid.set_src_endpoint(_sid_framer++); //increment for next setup + sid.set_src_endpoint(_sid_framer++); // increment for next setup // TODO Move all of this setup_mb() // Program the X300 to recognise it's own local address. mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_XB_LOCAL), address.get_dst_addr()); - // Program CAM entry for outgoing packets matching a X300 resource (for example a Radio) - // This type of packet matches the XB_LOCAL address and is looked up in the upper half of the CAM - mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, 256 + address.get_dst_endpoint()), address.get_dst_xbarport()); + // Program CAM entry for outgoing packets matching a X300 resource (for example a + // Radio) This type of packet matches the XB_LOCAL address and is looked up in the + // upper half of the CAM + mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, 256 + address.get_dst_endpoint()), + address.get_dst_xbarport()); // Program CAM entry for returning packets to us (for example GR host via Eth0) - // This type of packet does not match the XB_LOCAL address and is looked up in the lower half of the CAM + // This type of packet does not match the XB_LOCAL address and is looked up in the + // lower half of the CAM mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, 0 + src_addr), src_dst); - UHD_LOGGER_TRACE("X300") << "done router config for sid " << sid ; + UHD_LOGGER_TRACE("X300") << "done router config for sid " << sid; return sid; } @@ -1493,95 +1491,123 @@ uhd::sid_t x300_impl::allocate_sid( /*********************************************************************** * clock and time control logic **********************************************************************/ -void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb) +void x300_impl::set_time_source_out(mboard_members_t& mb, const bool enb) { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_OUT_EN, enb?1:0); + mb.fw_regmap->clock_ctrl_reg.write( + fw_regmap_t::clk_ctrl_reg_t::PPS_OUT_EN, enb ? 1 : 0); } -void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source) +void x300_impl::update_clock_source(mboard_members_t& mb, const std::string& source) { - //Optimize for the case when the current source is internal and we are trying - //to set it to internal. This is the only case where we are guaranteed that - //the clock has not gone away so we can skip setting the MUX and reseting the LMK. - const bool reconfigure_clks = (mb.current_refclk_src != "internal") or (source != "internal"); + // Optimize for the case when the current source is internal and we are trying + // to set it to internal. This is the only case where we are guaranteed that + // the clock has not gone away so we can skip setting the MUX and reseting the LMK. + const bool reconfigure_clks = (mb.current_refclk_src != "internal") + or (source != "internal"); if (reconfigure_clks) { - //Update the clock MUX on the motherboard to select the requested source + // Update the clock MUX on the motherboard to select the requested source if (source == "internal") { - mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); + mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, + fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 1); } else if (source == "external") { - mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); + mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, + fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0); } else if (source == "gpsdo") { - mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); + mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, + fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0); } else { throw uhd::key_error("update_clock_source: unknown source: " + source); } mb.fw_regmap->clock_ctrl_reg.flush(); - //Reset the LMK to make sure it re-locks to the new reference + // Reset the LMK to make sure it re-locks to the new reference mb.clock->reset_clocks(); } - //Wait for the LMK to lock (always, as a sanity check that the clock is useable) - //* Currently the LMK can take as long as 30 seconds to lock to a reference but we don't + // Wait for the LMK to lock (always, as a sanity check that the clock is useable) + //* Currently the LMK can take as long as 30 seconds to lock to a reference but we + // don't //* want to wait that long during initialization. - //TODO: Need to verify timeout and settings to make sure lock can be achieved in < 1.0 seconds + // TODO: Need to verify timeout and settings to make sure lock can be achieved in + // < 1.0 seconds double timeout = mb.initialization_done ? 30.0 : 1.0; - //The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may - //lead to locking issues. So, disable the ref-locked check for older (unsupported) boards. + // The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may + // lead to locking issues. So, disable the ref-locked check for older (unsupported) + // boards. if (mb.hw_rev > 4) { - if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout)) { - //failed to lock on reference + if (not wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout)) { + // failed to lock on reference if (mb.initialization_done) { - throw uhd::runtime_error((boost::format("Reference Clock PLL failed to lock to %s source.") % source).str()); + throw uhd::runtime_error( + (boost::format("Reference Clock PLL failed to lock to %s source.") + % source) + .str()); } else { - //TODO: Re-enable this warning when we figure out a reliable lock time - //UHD_LOGGER_WARNING("X300") << "Reference clock failed to lock to " + source + " during device initialization. " << - // "Check for the lock before operation or ignore this warning if using another clock source." ; + // TODO: Re-enable this warning when we figure out a reliable lock time + // UHD_LOGGER_WARNING("X300") << "Reference clock failed to lock to " + + // source + " during device initialization. " << + // "Check for the lock before operation or ignore this warning if using + // another clock source." ; } } } if (reconfigure_clks) { - //Reset the radio clock PLL in the FPGA - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_RADIO_CLK_PLL); + // Reset the radio clock PLL in the FPGA + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_RADIO_CLK_PLL); mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0); - //Wait for radio clock PLL to lock - if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK, 0.01)) { - throw uhd::runtime_error((boost::format("Reference Clock PLL in FPGA failed to lock to %s source.") % source).str()); + // Wait for radio clock PLL to lock + if (not wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK, 0.01)) { + throw uhd::runtime_error( + (boost::format("Reference Clock PLL in FPGA failed to lock to %s source.") + % source) + .str()); } - //Reset the IDELAYCTRL used to calibrate the data interface delays - mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_ADC_IDELAYCTRL); + // Reset the IDELAYCTRL used to calibrate the data interface delays + mb.zpu_ctrl->poke32( + SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), ZPU_SR_SW_RST_ADC_IDELAYCTRL); mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0); - //Wait for the ADC IDELAYCTRL to be ready - if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK, 0.01)) { - throw uhd::runtime_error((boost::format("ADC Calibration Clock in FPGA failed to lock to %s source.") % source).str()); + // Wait for the ADC IDELAYCTRL to be ready + if (not wait_for_clk_locked( + mb, fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK, 0.01)) { + throw uhd::runtime_error( + (boost::format( + "ADC Calibration Clock in FPGA failed to lock to %s source.") + % source) + .str()); } // Reset ADCs and DACs - for(rfnoc::x300_radio_ctrl_impl::sptr r: mb.radios) { + for (rfnoc::x300_radio_ctrl_impl::sptr r : mb.radios) { r->reset_codec(); } } - //Update cache value + // Update cache value mb.current_refclk_src = source; } -void x300_impl::update_time_source(mboard_members_t &mb, const std::string &source) +void x300_impl::update_time_source(mboard_members_t& mb, const std::string& source) { if (source == "internal") { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); + mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, + fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL); } else if (source == "external") { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); + mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, + fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL); } else if (source == "gpsdo") { - mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); + mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, + fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO); } else { throw uhd::key_error("update_time_source: unknown source: " + source); } @@ -1589,15 +1615,17 @@ void x300_impl::update_time_source(mboard_members_t &mb, const std::string &sour /* TODO - Implement intelligent PPS detection //check for valid pps if (!is_pps_present(mb)) { - throw uhd::runtime_error((boost::format("The %d PPS was not detected. Please check the PPS source and try again.") % source).str()); + throw uhd::runtime_error((boost::format("The %d PPS was not detected. Please + check the PPS source and try again.") % source).str()); } */ } -void x300_impl::sync_times(mboard_members_t &mb, const uhd::time_spec_t& t) +void x300_impl::sync_times(mboard_members_t& mb, const uhd::time_spec_t& t) { - std::vector<rfnoc::block_id_t> radio_ids = find_blocks<rfnoc::x300_radio_ctrl_impl>("Radio"); - for(const rfnoc::block_id_t &id: radio_ids) { + std::vector<rfnoc::block_id_t> radio_ids = + find_blocks<rfnoc::x300_radio_ctrl_impl>("Radio"); + for (const rfnoc::block_id_t& id : radio_ids) { get_block_ctrl<rfnoc::x300_radio_ctrl_impl>(id)->set_time_sync(t); } @@ -1608,9 +1636,8 @@ void x300_impl::sync_times(mboard_members_t &mb, const uhd::time_spec_t& t) bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, uint32_t which, double timeout) { - const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(int64_t(timeout * 1000)); + const auto timeout_time = std::chrono::steady_clock::now() + + std::chrono::milliseconds(int64_t(timeout * 1000)); do { if (mb.fw_regmap->clock_status_reg.read(which) == 1) { return true; @@ -1618,16 +1645,21 @@ bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, uint32_t which, double std::this_thread::sleep_for(std::chrono::milliseconds(1)); } while (std::chrono::steady_clock::now() < timeout_time); - //Check one last time - return (mb.fw_regmap->clock_status_reg.read(which)==1); + // Check one last time + return (mb.fw_regmap->clock_status_reg.read(which) == 1); } sensor_value_t x300_impl::get_ref_locked(mboard_members_t& mb) { mb.fw_regmap->clock_status_reg.refresh(); - const bool lock = (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::LMK_LOCK)==1) && - (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK)==1) && - (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK)==1); + const bool lock = + (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::LMK_LOCK) == 1) + && (mb.fw_regmap->clock_status_reg.get( + fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK) + == 1) + && (mb.fw_regmap->clock_status_reg.get( + fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK) + == 1); return sensor_value_t("Ref", lock, "locked", "unlocked"); } @@ -1635,11 +1667,13 @@ bool x300_impl::is_pps_present(mboard_members_t& mb) { // The ZPU_RB_CLK_STATUS_PPS_DETECT bit toggles with each rising edge of the PPS. // We monitor it for up to 1.5 seconds looking for it to toggle. - uint32_t pps_detect = mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT); - for (int i = 0; i < 15; i++) - { + uint32_t pps_detect = + mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT); + for (int i = 0; i < 15; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (pps_detect != mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT)) + if (pps_detect + != mb.fw_regmap->clock_status_reg.read( + fw_regmap_t::clk_status_reg_t::PPS_DETECT)) return true; } return false; @@ -1658,22 +1692,18 @@ void x300_impl::claimer_loop(wb_iface::sptr iface) x300_impl::claim_status_t x300_impl::claim_status(wb_iface::sptr iface) { claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive - auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::seconds(1); - while (std::chrono::steady_clock::now() < timeout_time) - { - //If timed out, then device is definitely unclaimed - if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) - { + auto timeout_time = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < timeout_time) { + // If timed out, then device is definitely unclaimed + if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) { claim_status = UNCLAIMED; break; } - //otherwise check claim src to determine if another thread with the same src has claimed the device + // otherwise check claim src to determine if another thread with the same src has + // claimed the device uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); - if (hash == 0) - { + if (hash == 0) { // A non-zero claim status and an empty hash means the claim might // be in the process of being released. This is possible because // older firmware takes a long time to update the status. Wait and @@ -1696,20 +1726,17 @@ void x300_impl::claim(wb_iface::sptr iface) bool x300_impl::try_to_claim(wb_iface::sptr iface, long timeout_ms) { const auto timeout_time = - std::chrono::steady_clock::now() - + std::chrono::milliseconds(timeout_ms); - while (1) - { + std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms); + while (1) { claim_status_t status = claim_status(iface); - if (status == UNCLAIMED) - { + if (status == UNCLAIMED) { claim(iface); - // It takes the claimer 10ms to update status, so wait 20ms before verifying claim + // It takes the claimer 10ms to update status, so wait 20ms before verifying + // claim std::this_thread::sleep_for(std::chrono::milliseconds(20)); continue; } - if (status == CLAIMED_BY_US) - { + if (status == CLAIMED_BY_US) { break; } if (std::chrono::steady_clock::now() > timeout_time) { @@ -1730,57 +1757,62 @@ void x300_impl::release(wb_iface::sptr iface) /*********************************************************************** * Frame size detection **********************************************************************/ -x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &addr, - const frame_size_t &user_frame_size) +x300_impl::frame_size_t x300_impl::determine_max_frame_size( + const std::string& addr, const frame_size_t& user_frame_size) { - udp_simple::sptr udp = udp_simple::make_connected(addr, - BOOST_STRINGIZE(X300_MTU_DETECT_UDP_PORT)); + udp_simple::sptr udp = + udp_simple::make_connected(addr, BOOST_STRINGIZE(X300_MTU_DETECT_UDP_PORT)); - std::vector<uint8_t> buffer(std::max(user_frame_size.recv_frame_size, user_frame_size.send_frame_size)); - x300_mtu_t *request = reinterpret_cast<x300_mtu_t *>(&buffer.front()); - static const double echo_timeout = 0.020; //20 ms + std::vector<uint8_t> buffer( + std::max(user_frame_size.recv_frame_size, user_frame_size.send_frame_size)); + x300_mtu_t* request = reinterpret_cast<x300_mtu_t*>(&buffer.front()); + static const double echo_timeout = 0.020; // 20 ms - //test holler - check if its supported in this fw version + // test holler - check if its supported in this fw version request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); - request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); + request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t))); udp->recv(boost::asio::buffer(buffer), echo_timeout); if (!(uhd::ntohx<uint32_t>(request->flags) & X300_MTU_DETECT_ECHO_REPLY)) throw uhd::not_implemented_error("Holler protocol not implemented"); - //Reducing range of (min,max) by setting max value to 10gig max_frame_size as larger sizes are not supported + // Reducing range of (min,max) by setting max value to 10gig max_frame_size as larger + // sizes are not supported size_t min_recv_frame_size = sizeof(x300_mtu_t); - size_t max_recv_frame_size = std::min(user_frame_size.recv_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); + size_t max_recv_frame_size = + std::min(user_frame_size.recv_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); size_t min_send_frame_size = sizeof(x300_mtu_t); - size_t max_send_frame_size = std::min(user_frame_size.send_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); + size_t max_send_frame_size = + std::min(user_frame_size.send_frame_size, x300::DATA_FRAME_MAX_SIZE) & size_t(~3); UHD_LOGGER_DEBUG("X300") << "Determining maximum frame size... "; - while (min_recv_frame_size < max_recv_frame_size) - { - size_t test_frame_size = (max_recv_frame_size/2 + min_recv_frame_size/2 + 3) & ~3; + while (min_recv_frame_size < max_recv_frame_size) { + size_t test_frame_size = (max_recv_frame_size / 2 + min_recv_frame_size / 2 + 3) + & ~3; - request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); - request->size = uhd::htonx<uint32_t>(test_frame_size); - udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t))); + request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); + request->size = uhd::htonx<uint32_t>(test_frame_size); + udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t))); - size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout); + size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout); - if (len >= test_frame_size) - min_recv_frame_size = test_frame_size; - else - max_recv_frame_size = test_frame_size - 4; + if (len >= test_frame_size) + min_recv_frame_size = test_frame_size; + else + max_recv_frame_size = test_frame_size - 4; } - if(min_recv_frame_size < IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER) { - throw uhd::runtime_error("System receive MTU size is less than the minimum required by the IP protocol."); + if (min_recv_frame_size < IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER) { + throw uhd::runtime_error("System receive MTU size is less than the minimum " + "required by the IP protocol."); } - while (min_send_frame_size < max_send_frame_size) - { - size_t test_frame_size = (max_send_frame_size/2 + min_send_frame_size/2 + 3) & ~3; + while (min_send_frame_size < max_send_frame_size) { + size_t test_frame_size = (max_send_frame_size / 2 + min_send_frame_size / 2 + 3) + & ~3; request->flags = uhd::htonx<uint32_t>(X300_MTU_DETECT_ECHO_REQUEST); - request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); + request->size = uhd::htonx<uint32_t>(sizeof(x300_mtu_t)); udp->send(boost::asio::buffer(buffer, test_frame_size)); size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout); @@ -1793,8 +1825,9 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a max_send_frame_size = test_frame_size - 4; } - if(min_send_frame_size < IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER) { - throw uhd::runtime_error("System send MTU size is less than the minimum required by the IP protocol."); + if (min_send_frame_size < IP_PROTOCOL_MIN_MTU_SIZE - IP_PROTOCOL_UDP_PLUS_IP_HEADER) { + throw uhd::runtime_error( + "System send MTU size is less than the minimum required by the IP protocol."); } frame_size_t frame_size; @@ -1803,8 +1836,8 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a // of the recv and send frame sizes. frame_size.recv_frame_size = std::min(min_recv_frame_size, min_send_frame_size); frame_size.send_frame_size = std::min(min_recv_frame_size, min_send_frame_size); - UHD_LOGGER_INFO("X300") - << "Maximum frame size: " << frame_size.send_frame_size << " bytes."; + UHD_LOGGER_INFO("X300") << "Maximum frame size: " << frame_size.send_frame_size + << " bytes."; return frame_size; } @@ -1812,10 +1845,8 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a * compat checks **********************************************************************/ -void x300_impl::check_fw_compat( - const fs_path &mb_path, - const mboard_members_t &members -) { +void x300_impl::check_fw_compat(const fs_path& mb_path, const mboard_members_t& members) +{ auto iface = members.zpu_ctrl; const uint32_t compat_num = iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_COMPAT_NUM)); @@ -1826,78 +1857,75 @@ void x300_impl::check_fw_compat( const std::string image_loader_path = (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); const std::string image_loader_cmd = - str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") - % image_loader_path - % (members.xport_path == "eth" ? "addr" - : "resource") - % members.get_pri_eth().addr); - - throw uhd::runtime_error(str(boost::format( - "Expected firmware compatibility number %d, but got %d:\n" - "The FPGA/firmware image on your device is not compatible with this host code build.\n" - "Download the appropriate FPGA images for this version of UHD.\n" - "%s\n\n" - "Then burn a new image to the on-board flash storage of your\n" - "USRP X3xx device using the image loader utility. " - "Use this command:\n\n%s\n\n" - "For more information, refer to the UHD manual:\n\n" - " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash" - ) % int(X300_FW_COMPAT_MAJOR) % compat_major - % print_utility_error("uhd_images_downloader.py") - % image_loader_cmd)); + str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") % image_loader_path + % (members.xport_path == "eth" ? "addr" : "resource") + % members.get_pri_eth().addr); + + throw uhd::runtime_error( + str(boost::format( + "Expected firmware compatibility number %d, but got %d:\n" + "The FPGA/firmware image on your device is not compatible with this " + "host code build.\n" + "Download the appropriate FPGA images for this version of UHD.\n" + "%s\n\n" + "Then burn a new image to the on-board flash storage of your\n" + "USRP X3xx device using the image loader utility. " + "Use this command:\n\n%s\n\n" + "For more information, refer to the UHD manual:\n\n" + " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash") + % int(X300_FW_COMPAT_MAJOR) % compat_major + % print_utility_error("uhd_images_downloader.py") % image_loader_cmd)); } _tree->create<std::string>(mb_path / "fw_version") .set(str(boost::format("%u.%u") % compat_major % compat_minor)); } -void x300_impl::check_fpga_compat(const fs_path &mb_path, const mboard_members_t &members) +void x300_impl::check_fpga_compat(const fs_path& mb_path, const mboard_members_t& members) { uint32_t compat_num = members.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_COMPAT_NUM)); uint32_t compat_major = (compat_num >> 16); uint32_t compat_minor = (compat_num & 0xffff); - if (compat_major != X300_FPGA_COMPAT_MAJOR) - { - std::string image_loader_path = (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); - std::string image_loader_cmd = str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") - % image_loader_path - % (members.xport_path == "eth" ? "addr" - : "resource") - % members.get_pri_eth().addr); - - throw uhd::runtime_error(str(boost::format( - "Expected FPGA compatibility number %d, but got %d:\n" - "The FPGA image on your device is not compatible with this host code build.\n" - "Download the appropriate FPGA images for this version of UHD.\n" - "%s\n\n" - "Then burn a new image to the on-board flash storage of your\n" - "USRP X3xx device using the image loader utility. Use this command:\n\n%s\n\n" - "For more information, refer to the UHD manual:\n\n" - " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash" - ) % int(X300_FPGA_COMPAT_MAJOR) % compat_major - % print_utility_error("uhd_images_downloader.py") - % image_loader_cmd)); + if (compat_major != X300_FPGA_COMPAT_MAJOR) { + std::string image_loader_path = + (fs::path(uhd::get_pkg_path()) / "bin" / "uhd_image_loader").string(); + std::string image_loader_cmd = + str(boost::format("\"%s\" --args=\"type=x300,%s=%s\"") % image_loader_path + % (members.xport_path == "eth" ? "addr" : "resource") + % members.get_pri_eth().addr); + + throw uhd::runtime_error( + str(boost::format( + "Expected FPGA compatibility number %d, but got %d:\n" + "The FPGA image on your device is not compatible with this host code " + "build.\n" + "Download the appropriate FPGA images for this version of UHD.\n" + "%s\n\n" + "Then burn a new image to the on-board flash storage of your\n" + "USRP X3xx device using the image loader utility. Use this " + "command:\n\n%s\n\n" + "For more information, refer to the UHD manual:\n\n" + " http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_flash") + % int(X300_FPGA_COMPAT_MAJOR) % compat_major + % print_utility_error("uhd_images_downloader.py") % image_loader_cmd)); } - _tree->create<std::string>(mb_path / "fpga_version").set(str(boost::format("%u.%u") - % compat_major % compat_minor)); - - const uint32_t git_hash = members.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, - ZPU_RB_GIT_HASH)); - const std::string git_hash_str = str( - boost::format("%07x%s") - % (git_hash & 0x0FFFFFFF) - % ((git_hash & 0xF0000000) ? "-dirty" : "") - ); + _tree->create<std::string>(mb_path / "fpga_version") + .set(str(boost::format("%u.%u") % compat_major % compat_minor)); + + const uint32_t git_hash = + members.zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_GIT_HASH)); + const std::string git_hash_str = str(boost::format("%07x%s") % (git_hash & 0x0FFFFFFF) + % ((git_hash & 0xF0000000) ? "-dirty" : "")); _tree->create<std::string>(mb_path / "fpga_version_hash").set(git_hash_str); UHD_LOG_DEBUG("X300", "Using FPGA version: " << compat_major << "." << compat_minor - << " git hash: " << git_hash_str); + << " git hash: " << git_hash_str); } x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie( - const std::string& resource, const std::string& rpc_port) + const std::string& resource, const std::string& rpc_port) { - //Detect the PCIe product ID to distinguish between X300 and X310 + // Detect the PCIe product ID to distinguish between X300 and X310 nirio_status status = NiRio_Status_Success; uint32_t pid; niriok_proxy::sptr discovery_proxy = @@ -1911,20 +1939,18 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie( } } - UHD_LOGGER_WARNING("X300") << - "NI-RIO Error -- unable to determine motherboard type!"; + UHD_LOGGER_WARNING("X300") << "NI-RIO Error -- unable to determine motherboard type!"; return UNKNOWN; } x300_impl::x300_mboard_t x300_impl::get_mb_type_from_eeprom( - const uhd::usrp::mboard_eeprom_t& mb_eeprom) + const uhd::usrp::mboard_eeprom_t& mb_eeprom) { - if (not mb_eeprom["product"].empty()) - { + if (not mb_eeprom["product"].empty()) { uint16_t product_num = 0; try { product_num = boost::lexical_cast<uint16_t>(mb_eeprom["product"]); - } catch (const boost::bad_lexical_cast &) { + } catch (const boost::bad_lexical_cast&) { product_num = 0; } diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 9de68a697..c58440d54 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -8,36 +8,34 @@ #ifndef INCLUDED_X300_IMPL_HPP #define INCLUDED_X300_IMPL_HPP -#include "x300_radio_ctrl_impl.hpp" +#include "../device3/device3_impl.hpp" #include "x300_clock_ctrl.hpp" -#include "x300_fw_common.h" -#include "x300_regs.hpp" #include "x300_defaults.hpp" #include "x300_device_args.hpp" - -#include "../device3/device3_impl.hpp" +#include "x300_fw_common.h" +#include "x300_radio_ctrl_impl.hpp" +#include "x300_regs.hpp" #include <uhd/property_tree.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/usrp/subdev_spec.hpp> -#include <uhd/types/sensors.hpp> -#include <uhd/transport/udp_simple.hpp> //mtu -#include <uhd/usrp/gps_ctrl.hpp> +#include <uhd/transport/muxed_zero_copy_if.hpp> #include <uhd/transport/nirio/niusrprio_session.h> +#include <uhd/transport/udp_simple.hpp> //mtu #include <uhd/transport/vrt_if_packet.hpp> -#include <uhd/transport/muxed_zero_copy_if.hpp> +#include <uhd/types/sensors.hpp> +#include <uhd/usrp/gps_ctrl.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/usrp/subdev_spec.hpp> ///////////// RFNOC ///////////////////// #include <uhd/rfnoc/block_ctrl.hpp> ///////////// RFNOC ///////////////////// -#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp> #include <uhdlib/usrp/common/recv_packet_demuxer_3000.hpp> +#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp> #include <boost/dynamic_bitset.hpp> #include <boost/weak_ptr.hpp> #include <atomic> // Ethernet ports -enum x300_eth_iface_t -{ +enum x300_eth_iface_t { X300_IFACE_NONE = 0, X300_IFACE_ETH0 = 1, X300_IFACE_ETH1 = 2, @@ -53,47 +51,46 @@ struct x300_eth_conn_t uhd::uart_iface::sptr x300_make_uart_iface(uhd::wb_iface::sptr iface); -uhd::wb_iface::sptr x300_make_ctrl_iface_enet(uhd::transport::udp_simple::sptr udp, bool enable_errors = true); -uhd::wb_iface::sptr x300_make_ctrl_iface_pcie(uhd::niusrprio::niriok_proxy::sptr drv_proxy, bool enable_errors = true); +uhd::wb_iface::sptr x300_make_ctrl_iface_enet( + uhd::transport::udp_simple::sptr udp, bool enable_errors = true); +uhd::wb_iface::sptr x300_make_ctrl_iface_pcie( + uhd::niusrprio::niriok_proxy::sptr drv_proxy, bool enable_errors = true); -uhd::device_addrs_t x300_find(const uhd::device_addr_t &hint_); +uhd::device_addrs_t x300_find(const uhd::device_addr_t& hint_); class x300_impl : public uhd::usrp::device3_impl { public: - - x300_impl(const uhd::device_addr_t &); - void setup_mb(const size_t which, const uhd::device_addr_t &); + x300_impl(const uhd::device_addr_t&); + void setup_mb(const size_t which, const uhd::device_addr_t&); ~x300_impl(void); // device claim functions - enum claim_status_t {UNCLAIMED, CLAIMED_BY_US, CLAIMED_BY_OTHER}; + enum claim_status_t { UNCLAIMED, CLAIMED_BY_US, CLAIMED_BY_OTHER }; static claim_status_t claim_status(uhd::wb_iface::sptr iface); static void claim(uhd::wb_iface::sptr iface); static bool try_to_claim(uhd::wb_iface::sptr iface, long timeout = 2000); static void release(uhd::wb_iface::sptr iface); - enum x300_mboard_t { - USRP_X300_MB, USRP_X310_MB, USRP_X310_MB_NI_2974, UNKNOWN - }; - static x300_mboard_t get_mb_type_from_pcie(const std::string& resource, const std::string& rpc_port); - static x300_mboard_t get_mb_type_from_eeprom(const uhd::usrp::mboard_eeprom_t& mb_eeprom); + enum x300_mboard_t { USRP_X300_MB, USRP_X310_MB, USRP_X310_MB_NI_2974, UNKNOWN }; + static x300_mboard_t get_mb_type_from_pcie( + const std::string& resource, const std::string& rpc_port); + static x300_mboard_t get_mb_type_from_eeprom( + const uhd::usrp::mboard_eeprom_t& mb_eeprom); //! Read out the on-board EEPROM, convert to dict, and return static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr i2c); protected: - void subdev_to_blockid( - const uhd::usrp::subdev_spec_pair_t &spec, const size_t mb_i, - uhd::rfnoc::block_id_t &block_id, uhd::device_addr_t &block_args - ); + void subdev_to_blockid(const uhd::usrp::subdev_spec_pair_t& spec, + const size_t mb_i, + uhd::rfnoc::block_id_t& block_id, + uhd::device_addr_t& block_args); uhd::usrp::subdev_spec_pair_t blockid_to_subdev( - const uhd::rfnoc::block_id_t &blockid, const uhd::device_addr_t &block_args - ); + const uhd::rfnoc::block_id_t& blockid, const uhd::device_addr_t& block_args); private: - - //vector of member objects per motherboard + // vector of member objects per motherboard struct mboard_members_t { uhd::usrp::x300::x300_device_args_t args; @@ -109,7 +106,7 @@ private: // Discover the ethernet connections per motherboard void discover_eth(const uhd::usrp::mboard_eeprom_t mb_eeprom, - const std::vector<std::string> &ip_addrs); + const std::vector<std::string>& ip_addrs); // Get the primary ethernet connection inline const x300_eth_conn_t& get_pri_eth() const @@ -120,20 +117,20 @@ private: uhd::device_addr_t send_args; uhd::device_addr_t recv_args; bool if_pkt_is_big_endian; - uhd::niusrprio::niusrprio_session::sptr rio_fpga_interface; + uhd::niusrprio::niusrprio_session::sptr rio_fpga_interface; - //perifs in the zpu + // perifs in the zpu uhd::wb_iface::sptr zpu_ctrl; spi_core_3000::sptr zpu_spi; i2c_core_100_wb32::sptr zpu_i2c; - //other perifs on mboard + // other perifs on mboard x300_clock_ctrl::sptr clock; uhd::gps_ctrl::sptr gps; uhd::usrp::x300::fw_regmap_t::sptr fw_regmap; - //which FPGA image is loaded + // which FPGA image is loaded std::string loaded_fpga_image; size_t hw_rev; @@ -154,25 +151,23 @@ private: * * Note the SID is always the transmit SID (i.e. from host to device). */ - uint32_t allocate_pcie_dma_chan(const uhd::sid_t &tx_sid, const xport_type_t xport_type); + uint32_t allocate_pcie_dma_chan( + const uhd::sid_t& tx_sid, const xport_type_t xport_type); }; std::vector<mboard_members_t> _mb; - //task for periodically reclaiming the device from others + // task for periodically reclaiming the device from others void claimer_loop(uhd::wb_iface::sptr); std::atomic<size_t> _sid_framer; - uhd::sid_t allocate_sid( - mboard_members_t &mb, - const uhd::sid_t &address, + uhd::sid_t allocate_sid(mboard_members_t& mb, + const uhd::sid_t& address, const uint32_t src_addr, const uint32_t src_dst); - uhd::both_xports_t make_transport( - const uhd::sid_t &address, + uhd::both_xports_t make_transport(const uhd::sid_t& address, const xport_type_t xport_type, - const uhd::device_addr_t& args - ); + const uhd::device_addr_t& args); struct frame_size_t { @@ -186,24 +181,25 @@ private: * to the device and see which packet sizes actually work. This way, we can take * switches etc. into account which might live between the device and the host. */ - frame_size_t determine_max_frame_size(const std::string &addr, const frame_size_t &user_mtu); + frame_size_t determine_max_frame_size( + const std::string& addr, const frame_size_t& user_mtu); //////////////////////////////////////////////////////////////////// // - //Caching for transport interface re-use -- like sharing a DMA. - //The cache is optionally used by make_transport by use-case. - //The cache maps an ID string to a transport-ish object. - //The ID string identifies a purpose for the transport. + // Caching for transport interface re-use -- like sharing a DMA. + // The cache is optionally used by make_transport by use-case. + // The cache maps an ID string to a transport-ish object. + // The ID string identifies a purpose for the transport. // - //For recv, there is a demux cache, which maps a ID string - //to a recv demux object. When a demux is used, the underlying transport - //must never be used outside of the demux. Use demux->make_proxy(sid). + // For recv, there is a demux cache, which maps a ID string + // to a recv demux object. When a demux is used, the underlying transport + // must never be used outside of the demux. Use demux->make_proxy(sid). // uhd::dict<std::string, uhd::usrp::recv_packet_demuxer_3000::sptr> _demux_cache; // - //For send, there is a shared send xport, which maps an ID string - //to a transport capable of sending buffers. Send transports - //can be shared amongst multiple callers, unlike recv. + // For send, there is a shared send xport, which maps an ID string + // to a transport capable of sending buffers. Send transports + // can be shared amongst multiple callers, unlike recv. // uhd::dict<std::string, uhd::transport::zero_copy_if::sptr> _send_cache; // @@ -214,10 +210,10 @@ private: bool _ignore_cal_file; void update_clock_control(mboard_members_t&); - void initialize_clock_control(mboard_members_t &mb); + void initialize_clock_control(mboard_members_t& mb); void set_time_source_out(mboard_members_t&, const bool); - void update_clock_source(mboard_members_t&, const std::string &); - void update_time_source(mboard_members_t&, const std::string &); + void update_clock_source(mboard_members_t&, const std::string&); + void update_time_source(mboard_members_t&, const std::string&); void sync_times(mboard_members_t&, const uhd::time_spec_t&); uhd::sensor_value_t get_ref_locked(mboard_members_t& mb); @@ -225,13 +221,10 @@ private: bool is_pps_present(mboard_members_t& mb); //! Write the contents of an EEPROM dict to the on-board EEPROM - void set_mb_eeprom( - uhd::i2c_iface::sptr i2c, - const uhd::usrp::mboard_eeprom_t & - ); + void set_mb_eeprom(uhd::i2c_iface::sptr i2c, const uhd::usrp::mboard_eeprom_t&); - void check_fw_compat(const uhd::fs_path &mb_path, const mboard_members_t &members); - void check_fpga_compat(const uhd::fs_path &mb_path, const mboard_members_t &members); + void check_fw_compat(const uhd::fs_path& mb_path, const mboard_members_t& members); + void check_fpga_compat(const uhd::fs_path& mb_path, const mboard_members_t& members); /// More IO stuff uhd::device_addr_t get_tx_hints(size_t mb_index); diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp index d833b3715..07e93173a 100644 --- a/host/lib/usrp/x300/x300_io_impl.cpp +++ b/host/lib/usrp/x300/x300_io_impl.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "x300_regs.hpp" #include "x300_impl.hpp" +#include "x300_regs.hpp" using namespace uhd; using namespace uhd::usrp; @@ -35,7 +35,7 @@ void x300_impl::post_streamer_hooks(direction_t dir) // Loop through all tx streamers. Find all radios connected to one // streamer. Sync those. - for(const boost::weak_ptr<uhd::tx_streamer> &streamer_w: _tx_streamers.vals()) { + for (const boost::weak_ptr<uhd::tx_streamer>& streamer_w : _tx_streamers.vals()) { const boost::shared_ptr<device3_send_packet_streamer> streamer = boost::dynamic_pointer_cast<device3_send_packet_streamer>(streamer_w.lock()); if (not streamer) { @@ -43,13 +43,15 @@ void x300_impl::post_streamer_hooks(direction_t dir) } std::vector<rfnoc::x300_radio_ctrl_impl::sptr> radio_ctrl_blks = - streamer->get_terminator()->find_downstream_node<rfnoc::x300_radio_ctrl_impl>(); + streamer->get_terminator() + ->find_downstream_node<rfnoc::x300_radio_ctrl_impl>(); try { - //UHD_LOGGER_INFO("X300") << "[X300] syncing " << radio_ctrl_blks.size() << " radios " ; + // UHD_LOGGER_INFO("X300") << "[X300] syncing " << radio_ctrl_blks.size() << " + // radios " ; rfnoc::x300_radio_ctrl_impl::synchronize_dacs(radio_ctrl_blks); - } - catch(const uhd::io_error &ex) { - throw uhd::io_error(str(boost::format("Failed to sync DACs! %s ") % ex.what())); + } catch (const uhd::io_error& ex) { + throw uhd::io_error( + str(boost::format("Failed to sync DACs! %s ") % ex.what())); } } } diff --git a/host/lib/usrp/x300/x300_mb_eeprom.cpp b/host/lib/usrp/x300/x300_mb_eeprom.cpp index b3ebf6101..663f4c9db 100644 --- a/host/lib/usrp/x300/x300_mb_eeprom.cpp +++ b/host/lib/usrp/x300/x300_mb_eeprom.cpp @@ -5,38 +5,38 @@ // #include "x300_impl.hpp" -#include <uhdlib/utils/eeprom_utils.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/types/serial.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhdlib/utils/eeprom_utils.hpp> namespace { - const uint8_t X300_EEPROM_ADDR = 0x50; - - struct x300_eeprom_map - { - //identifying numbers - unsigned char revision[2]; - unsigned char product[2]; - unsigned char revision_compat[2]; - uint8_t _pad0[2]; - - //all the mac addrs - uint8_t mac_addr0[6]; - uint8_t _pad1[2]; - uint8_t mac_addr1[6]; - uint8_t _pad2[2]; - - //all the IP addrs - uint32_t gateway; - uint32_t subnet[4]; - uint32_t ip_addr[4]; - uint8_t _pad3[16]; - - //names and serials - unsigned char name[NAME_MAX_LEN]; - unsigned char serial[SERIAL_LEN]; - }; -} +const uint8_t X300_EEPROM_ADDR = 0x50; + +struct x300_eeprom_map +{ + // identifying numbers + unsigned char revision[2]; + unsigned char product[2]; + unsigned char revision_compat[2]; + uint8_t _pad0[2]; + + // all the mac addrs + uint8_t mac_addr0[6]; + uint8_t _pad1[2]; + uint8_t mac_addr1[6]; + uint8_t _pad2[2]; + + // all the IP addrs + uint32_t gateway; + uint32_t subnet[4]; + uint32_t ip_addr[4]; + uint8_t _pad3[16]; + + // names and serials + unsigned char name[NAME_MAX_LEN]; + unsigned char serial[SERIAL_LEN]; +}; +} // namespace using namespace uhd; using uhd::usrp::mboard_eeprom_t; @@ -51,170 +51,150 @@ mboard_eeprom_t x300_impl::get_mb_eeprom(uhd::i2c_iface::sptr iface) return mb_eeprom; } - //extract the revision number + // extract the revision number mb_eeprom["revision"] = uint16_bytes_to_string( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, revision), - bytes.begin() + (offsetof(x300_eeprom_map, revision)+2)) - ); + byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, revision), + bytes.begin() + (offsetof(x300_eeprom_map, revision) + 2))); - //extract the revision compat number + // extract the revision compat number mb_eeprom["revision_compat"] = uint16_bytes_to_string( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, revision_compat), - bytes.begin() + (offsetof(x300_eeprom_map, revision_compat)+2)) - ); + byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, revision_compat), + bytes.begin() + (offsetof(x300_eeprom_map, revision_compat) + 2))); - //extract the product code + // extract the product code mb_eeprom["product"] = uint16_bytes_to_string( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, product), - bytes.begin() + (offsetof(x300_eeprom_map, product)+2)) - ); + byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, product), + bytes.begin() + (offsetof(x300_eeprom_map, product) + 2))); - //extract the mac addresses + // extract the mac addresses mb_eeprom["mac-addr0"] = mac_addr_t::from_bytes( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, mac_addr0), - bytes.begin() + (offsetof(x300_eeprom_map, mac_addr0)+6)) - ).to_string(); + byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, mac_addr0), + bytes.begin() + (offsetof(x300_eeprom_map, mac_addr0) + 6))) + .to_string(); mb_eeprom["mac-addr1"] = mac_addr_t::from_bytes( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, mac_addr1), - bytes.begin() + (offsetof(x300_eeprom_map, mac_addr1)+6)) - ).to_string(); + byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, mac_addr1), + bytes.begin() + (offsetof(x300_eeprom_map, mac_addr1) + 6))) + .to_string(); - //extract the ip addresses + // extract the ip addresses boost::asio::ip::address_v4::bytes_type ip_addr_bytes; - byte_copy( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, gateway), - bytes.begin() + (offsetof(x300_eeprom_map, gateway)+4)), - ip_addr_bytes - ); + byte_copy(byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, gateway), + bytes.begin() + (offsetof(x300_eeprom_map, gateway) + 4)), + ip_addr_bytes); mb_eeprom["gateway"] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); - for (size_t i = 0; i < 4; i++) - { - const std::string n(1, char(i)+'0'); + for (size_t i = 0; i < 4; i++) { + const std::string n(1, char(i) + '0'); byte_copy( - byte_vector_t( - bytes.begin() + (offsetof(x300_eeprom_map, ip_addr)+(i*4)), - bytes.begin() + (offsetof(x300_eeprom_map, ip_addr)+(i*4)+4)), - ip_addr_bytes - ); - mb_eeprom["ip-addr"+n] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); + byte_vector_t(bytes.begin() + (offsetof(x300_eeprom_map, ip_addr) + (i * 4)), + bytes.begin() + (offsetof(x300_eeprom_map, ip_addr) + (i * 4) + 4)), + ip_addr_bytes); + mb_eeprom["ip-addr" + n] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); byte_copy( - byte_vector_t( - bytes.begin() + (offsetof(x300_eeprom_map, subnet)+(i*4)), - bytes.begin() + (offsetof(x300_eeprom_map, subnet)+(i*4)+4)), - ip_addr_bytes - ); - mb_eeprom["subnet"+n] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); + byte_vector_t(bytes.begin() + (offsetof(x300_eeprom_map, subnet) + (i * 4)), + bytes.begin() + (offsetof(x300_eeprom_map, subnet) + (i * 4) + 4)), + ip_addr_bytes); + mb_eeprom["subnet" + n] = boost::asio::ip::address_v4(ip_addr_bytes).to_string(); } - //extract the serial - mb_eeprom["serial"] = bytes_to_string( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, serial), - bytes.begin() + (offsetof(x300_eeprom_map, serial)+SERIAL_LEN)) - ); + // extract the serial + mb_eeprom["serial"] = + bytes_to_string(byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, serial), + bytes.begin() + (offsetof(x300_eeprom_map, serial) + SERIAL_LEN))); - //extract the name - mb_eeprom["name"] = bytes_to_string( - byte_vector_t( - bytes.begin() + offsetof(x300_eeprom_map, name), - bytes.begin() + (offsetof(x300_eeprom_map, name)+NAME_MAX_LEN)) - ); + // extract the name + mb_eeprom["name"] = + bytes_to_string(byte_vector_t(bytes.begin() + offsetof(x300_eeprom_map, name), + bytes.begin() + (offsetof(x300_eeprom_map, name) + NAME_MAX_LEN))); return mb_eeprom; } -void x300_impl::set_mb_eeprom( - i2c_iface::sptr iface, - const mboard_eeprom_t &mb_eeprom -) { +void x300_impl::set_mb_eeprom(i2c_iface::sptr iface, const mboard_eeprom_t& mb_eeprom) +{ const mboard_eeprom_t curr_eeprom = get_mb_eeprom(iface); // Check for duplicate MAC and IP addresses - const std::vector<std::string> mac_keys{ - "mac-addr0", - "mac-addr1" - }; + const std::vector<std::string> mac_keys{"mac-addr0", "mac-addr1"}; const std::vector<std::string> ip_keys{ - "ip-addr0", - "ip-addr1", - "ip-addr2", - "ip-addr3" - }; + "ip-addr0", "ip-addr1", "ip-addr2", "ip-addr3"}; - //make sure there are no duplicate values + // make sure there are no duplicate values if (check_for_duplicates<uhd::mac_addr_t>( - "X300", mb_eeprom, curr_eeprom,"MAC address", mac_keys) or - check_for_duplicates<boost::asio::ip::address_v4>( - "X300", mb_eeprom, curr_eeprom, "IP address", ip_keys)) - { + "X300", mb_eeprom, curr_eeprom, "MAC address", mac_keys) + or check_for_duplicates<boost::asio::ip::address_v4>( + "X300", mb_eeprom, curr_eeprom, "IP address", ip_keys)) { throw uhd::value_error( "Duplicate values not permitted - write to EEPROM aborted"); } - //parse the revision number - if (mb_eeprom.has_key("revision")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, revision), - string_to_uint16_bytes(mb_eeprom["revision"]) - ); - - //parse the revision compat number - if (mb_eeprom.has_key("revision_compat")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, revision_compat), - string_to_uint16_bytes(mb_eeprom["revision_compat"]) - ); - - //parse the product code - if (mb_eeprom.has_key("product")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, product), - string_to_uint16_bytes(mb_eeprom["product"]) - ); - - //store the mac addresses - if (mb_eeprom.has_key("mac-addr0")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, mac_addr0), - mac_addr_t::from_string(mb_eeprom["mac-addr0"]).to_bytes() - ); - if (mb_eeprom.has_key("mac-addr1")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, mac_addr1), - mac_addr_t::from_string(mb_eeprom["mac-addr1"]).to_bytes() - ); - - //store the ip addresses + // parse the revision number + if (mb_eeprom.has_key("revision")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, revision), + string_to_uint16_bytes(mb_eeprom["revision"])); + + // parse the revision compat number + if (mb_eeprom.has_key("revision_compat")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, revision_compat), + string_to_uint16_bytes(mb_eeprom["revision_compat"])); + + // parse the product code + if (mb_eeprom.has_key("product")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, product), + string_to_uint16_bytes(mb_eeprom["product"])); + + // store the mac addresses + if (mb_eeprom.has_key("mac-addr0")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, mac_addr0), + mac_addr_t::from_string(mb_eeprom["mac-addr0"]).to_bytes()); + if (mb_eeprom.has_key("mac-addr1")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, mac_addr1), + mac_addr_t::from_string(mb_eeprom["mac-addr1"]).to_bytes()); + + // store the ip addresses byte_vector_t ip_addr_bytes(4); - if (mb_eeprom.has_key("gateway")){ - byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["gateway"]).to_bytes(), ip_addr_bytes); - iface->write_eeprom(X300_EEPROM_ADDR, offsetof(x300_eeprom_map, gateway), ip_addr_bytes); + if (mb_eeprom.has_key("gateway")) { + byte_copy( + boost::asio::ip::address_v4::from_string(mb_eeprom["gateway"]).to_bytes(), + ip_addr_bytes); + iface->write_eeprom( + X300_EEPROM_ADDR, offsetof(x300_eeprom_map, gateway), ip_addr_bytes); } - for (size_t i = 0; i < 4; i++) - { - const std::string n(1, char(i)+'0'); - if (mb_eeprom.has_key("ip-addr"+n)){ - byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"+n]).to_bytes(), ip_addr_bytes); - iface->write_eeprom(X300_EEPROM_ADDR, offsetof(x300_eeprom_map, ip_addr)+(i*4), ip_addr_bytes); + for (size_t i = 0; i < 4; i++) { + const std::string n(1, char(i) + '0'); + if (mb_eeprom.has_key("ip-addr" + n)) { + byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr" + n]) + .to_bytes(), + ip_addr_bytes); + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, ip_addr) + (i * 4), + ip_addr_bytes); } - if (mb_eeprom.has_key("subnet"+n)){ - byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["subnet"+n]).to_bytes(), ip_addr_bytes); - iface->write_eeprom(X300_EEPROM_ADDR, offsetof(x300_eeprom_map, subnet)+(i*4), ip_addr_bytes); + if (mb_eeprom.has_key("subnet" + n)) { + byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["subnet" + n]) + .to_bytes(), + ip_addr_bytes); + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, subnet) + (i * 4), + ip_addr_bytes); } } - //store the serial - if (mb_eeprom.has_key("serial")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, serial), - string_to_bytes(mb_eeprom["serial"], SERIAL_LEN) - ); - - //store the name - if (mb_eeprom.has_key("name")) iface->write_eeprom( - X300_EEPROM_ADDR, offsetof(x300_eeprom_map, name), - string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN) - ); + // store the serial + if (mb_eeprom.has_key("serial")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, serial), + string_to_bytes(mb_eeprom["serial"], SERIAL_LEN)); + + // store the name + if (mb_eeprom.has_key("name")) + iface->write_eeprom(X300_EEPROM_ADDR, + offsetof(x300_eeprom_map, name), + string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)); } diff --git a/host/lib/usrp/x300/x300_mb_eeprom_iface.cpp b/host/lib/usrp/x300/x300_mb_eeprom_iface.cpp index 630e8ce2b..12022ec24 100644 --- a/host/lib/usrp/x300/x300_mb_eeprom_iface.cpp +++ b/host/lib/usrp/x300/x300_mb_eeprom_iface.cpp @@ -19,12 +19,12 @@ #include "x300_mb_eeprom_iface.hpp" #include "x300_fw_common.h" -#include "x300_regs.hpp" #include "x300_impl.hpp" +#include "x300_regs.hpp" #include <uhd/exception.hpp> -#include <uhd/utils/platform.hpp> -#include <uhd/utils/log.hpp> #include <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/platform.hpp> #include <boost/thread.hpp> using namespace uhd; @@ -34,7 +34,6 @@ static const uint32_t X300_FW_SHMEM_IDENT_MIN_VERSION = 0x50001; class x300_mb_eeprom_iface_impl : public x300_mb_eeprom_iface { public: - x300_mb_eeprom_iface_impl(wb_iface::sptr wb, i2c_iface::sptr i2c) : _wb(wb), _i2c(i2c) { _compat_num = _wb->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_COMPAT_NUM)); @@ -50,14 +49,10 @@ public: * \param addr the address * \param buf the vector of bytes */ - void write_i2c( - uint16_t addr, - const byte_vector_t &buf - ) + void write_i2c(uint16_t addr, const byte_vector_t& buf) { UHD_ASSERT_THROW(addr == MBOARD_EEPROM_ADDR); - if (x300_impl::claim_status(_wb) != x300_impl::CLAIMED_BY_US) - { + if (x300_impl::claim_status(_wb) != x300_impl::CLAIMED_BY_US) { throw uhd::io_error("Attempted to write MB EEPROM without claim to device."); } _i2c->write_i2c(addr, buf); @@ -69,24 +64,18 @@ public: * \param num_bytes number of bytes to read * \return a vector of bytes */ - byte_vector_t read_i2c( - uint16_t addr, - size_t num_bytes - ) + byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) { UHD_ASSERT_THROW(addr == MBOARD_EEPROM_ADDR); byte_vector_t bytes; - if (_compat_num > X300_FW_SHMEM_IDENT_MIN_VERSION) - { + if (_compat_num > X300_FW_SHMEM_IDENT_MIN_VERSION) { bytes = read_eeprom(addr, 0, num_bytes); } else { x300_impl::claim_status_t status = x300_impl::claim_status(_wb); // Claim device before driving the I2C bus - if (status == x300_impl::CLAIMED_BY_US or x300_impl::try_to_claim(_wb)) - { + if (status == x300_impl::CLAIMED_BY_US or x300_impl::try_to_claim(_wb)) { bytes = _i2c->read_i2c(addr, num_bytes); - if (status != x300_impl::CLAIMED_BY_US) - { + if (status != x300_impl::CLAIMED_BY_US) { // We didn't originally have the claim, so give it up x300_impl::release(_wb); } @@ -101,15 +90,10 @@ public: * \param offset byte offset * \param buf the vector of bytes */ - void write_eeprom( - uint16_t addr, - uint16_t offset, - const byte_vector_t &buf - ) + void write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& buf) { UHD_ASSERT_THROW(addr == MBOARD_EEPROM_ADDR); - if (x300_impl::claim_status(_wb) != x300_impl::CLAIMED_BY_US) - { + if (x300_impl::claim_status(_wb) != x300_impl::CLAIMED_BY_US) { throw uhd::io_error("Attempted to write MB EEPROM without claim to device."); } _i2c->write_eeprom(addr, offset, buf); @@ -122,37 +106,31 @@ public: * \param num_bytes number of bytes to read * \return a vector of bytes */ - byte_vector_t read_eeprom( - uint16_t addr, - uint16_t offset, - size_t num_bytes - ) + byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes) { UHD_ASSERT_THROW(addr == MBOARD_EEPROM_ADDR); byte_vector_t bytes; x300_impl::claim_status_t status = x300_impl::claim_status(_wb); - if (_compat_num >= X300_FW_SHMEM_IDENT_MIN_VERSION) - { + if (_compat_num >= X300_FW_SHMEM_IDENT_MIN_VERSION) { // Get MB EEPROM data from firmware memory - if (num_bytes == 0) return bytes; + if (num_bytes == 0) + return bytes; size_t bytes_read = 0; - for (size_t word = offset / 4; bytes_read < num_bytes; word++) - { - uint32_t value = byteswap(_wb->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_IDENT + word))); - for (size_t byte = offset % 4; byte < 4 and bytes_read < num_bytes; byte++) - { + for (size_t word = offset / 4; bytes_read < num_bytes; word++) { + uint32_t value = + byteswap(_wb->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_IDENT + word))); + for (size_t byte = offset % 4; byte < 4 and bytes_read < num_bytes; + byte++) { bytes.push_back(uint8_t((value >> (byte * 8)) & 0xff)); bytes_read++; } } } else { // Claim device before driving the I2C bus - if (status == x300_impl::CLAIMED_BY_US or x300_impl::try_to_claim(_wb)) - { + if (status == x300_impl::CLAIMED_BY_US or x300_impl::try_to_claim(_wb)) { bytes = _i2c->read_eeprom(addr, offset, num_bytes); - if (status != x300_impl::CLAIMED_BY_US) - { + if (status != x300_impl::CLAIMED_BY_US) { // We didn't originally have the claim, so give it up x300_impl::release(_wb); } @@ -173,8 +151,8 @@ x300_mb_eeprom_iface::~x300_mb_eeprom_iface(void) /* NOP */ } -x300_mb_eeprom_iface::sptr x300_mb_eeprom_iface::make(wb_iface::sptr wb, i2c_iface::sptr i2c) +x300_mb_eeprom_iface::sptr x300_mb_eeprom_iface::make( + wb_iface::sptr wb, i2c_iface::sptr i2c) { return boost::make_shared<x300_mb_eeprom_iface_impl>(wb, i2c->eeprom16()); } - diff --git a/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp b/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp index dfc1eea6d..d323d6359 100644 --- a/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp +++ b/host/lib/usrp/x300/x300_mb_eeprom_iface.hpp @@ -10,9 +10,9 @@ #include <uhd/config.hpp> #include <uhd/types/serial.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> #include <uhd/types/wb_iface.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> class x300_mb_eeprom_iface : public uhd::i2c_iface { diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp index d0aadc55a..9057180e4 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp @@ -6,19 +6,19 @@ #include "x300_radio_ctrl_impl.hpp" #include "x300_dboard_iface.hpp" -#include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/utils/log.hpp> -#include <uhd/usrp/dboard_iface.hpp> #include <uhd/rfnoc/node_ctrl_base.hpp> #include <uhd/transport/chdr.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/usrp/dboard_iface.hpp> +#include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> #include <uhd/utils/safe_call.hpp> #include <uhdlib/rfnoc/wb_iface_adapter.hpp> -#include <uhdlib/usrp/cores/gpio_atr_3000.hpp> #include <uhdlib/usrp/common/apply_corrections.hpp> +#include <uhdlib/usrp/cores/gpio_atr_3000.hpp> #include <boost/algorithm/string.hpp> -#include <boost/make_shared.hpp> #include <boost/date_time/posix_time/posix_time_io.hpp> +#include <boost/make_shared.hpp> #include <chrono> #include <thread> @@ -33,26 +33,26 @@ static const size_t IO_MASTER_RADIO = 0; * Structors ***************************************************************************/ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl) - , _ignore_cal_file(false) +, _ignore_cal_file(false) { - UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::ctor() " ; + UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::ctor() "; //////////////////////////////////////////////////////////////////// // Set up basic info //////////////////////////////////////////////////////////////////// - _radio_type = (get_block_id().get_block_count() == 0) ? PRIMARY : SECONDARY; - _radio_slot = (get_block_id().get_block_count() == 0) ? "A" : "B"; + _radio_type = (get_block_id().get_block_count() == 0) ? PRIMARY : SECONDARY; + _radio_slot = (get_block_id().get_block_count() == 0) ? "A" : "B"; _radio_clk_rate = _tree->access<double>("master_clock_rate").get(); //////////////////////////////////////////////////////////////////// // Set up peripherals //////////////////////////////////////////////////////////////////// wb_iface::sptr ctrl = _get_ctrl(IO_MASTER_RADIO); - _regs = boost::make_shared<radio_regmap_t>(_radio_type==PRIMARY?0:1); + _regs = boost::make_shared<radio_regmap_t>(_radio_type == PRIMARY ? 0 : 1); _regs->initialize(*ctrl, true); - //Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1 - if (_radio_type==PRIMARY) { + // Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1 + if (_radio_type == PRIMARY) { _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1); _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0); _regs->misc_outs_reg.flush(); @@ -67,84 +67,100 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl) //////////////////////////////////////////////////////////////// _spi = spi_core_3000::make(ctrl, regs::sr_addr(radio_ctrl_impl::regs::SPI), - regs::rb_addr(radio_ctrl_impl::regs::RB_SPI) - ); + regs::rb_addr(radio_ctrl_impl::regs::RB_SPI)); _adc = x300_adc_ctrl::make(_spi, DB_ADC_SEN); _dac = x300_dac_ctrl::make(_spi, DB_DAC_SEN, _radio_clk_rate); - if (_radio_type==PRIMARY) { - _fp_gpio = gpio_atr::gpio_atr_3000::make(ctrl, - regs::sr_addr(regs::FP_GPIO), - regs::rb_addr(regs::RB_FP_GPIO) - ); - for(const gpio_atr::gpio_attr_map_t::value_type attr: gpio_atr::gpio_attr_map) { - switch (attr.first){ + if (_radio_type == PRIMARY) { + _fp_gpio = gpio_atr::gpio_atr_3000::make( + ctrl, regs::sr_addr(regs::FP_GPIO), regs::rb_addr(regs::RB_FP_GPIO)); + for (const gpio_atr::gpio_attr_map_t::value_type attr : gpio_atr::gpio_attr_map) { + switch (attr.first) { case usrp::gpio_atr::GPIO_SRC: - _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this](const std::vector<std::string>&){ - throw uhd::runtime_error("This device does not support setting the GPIO_SRC attribute."); - }); + _tree + ->create<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber([this](const std::vector<std::string>&) { + throw uhd::runtime_error("This device does not support " + "setting the GPIO_SRC attribute."); + }); break; case usrp::gpio_atr::GPIO_CTRL: case usrp::gpio_atr::GPIO_DDR: - _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second) - .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) - .add_coerced_subscriber([this, attr](const std::vector<std::string> str_val){ - uint32_t val = 0; - for(size_t i = 0 ; i < str_val.size() ; i++){ - val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i; - } - _fp_gpio->set_gpio_attr(attr.first, val); - }); + _tree + ->create<std::vector<std::string>>( + fs_path("gpio") / "FP0" / attr.second) + .set(std::vector<std::string>( + 32, usrp::gpio_atr::default_attr_value_map.at(attr.first))) + .add_coerced_subscriber( + [this, attr](const std::vector<std::string> str_val) { + uint32_t val = 0; + for (size_t i = 0; i < str_val.size(); i++) { + val += usrp::gpio_atr::gpio_attr_value_pair + .at(attr.second) + .at(str_val[i]) + << i; + } + _fp_gpio->set_gpio_attr(attr.first, val); + }); break; case usrp::gpio_atr::GPIO_READBACK: _tree->create<uint32_t>(fs_path("gpio") / "FP0" / "READBACK") - .set_publisher([this](){ - return _fp_gpio->read_gpio(); - }); + .set_publisher([this]() { return _fp_gpio->read_gpio(); }); break; default: _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second) - .set(0) - .add_coerced_subscriber([this, attr](const uint32_t val){ - _fp_gpio->set_gpio_attr(attr.first, val); - }); + .set(0) + .add_coerced_subscriber([this, attr](const uint32_t val) { + _fp_gpio->set_gpio_attr(attr.first, val); + }); } - } } //////////////////////////////////////////////////////////////// // create legacy codec control objects //////////////////////////////////////////////////////////////// - _tree->create<int>("rx_codecs" / _radio_slot / "gains"); //phony property so this dir exists - _tree->create<int>("tx_codecs" / _radio_slot / "gains"); //phony property so this dir exists + _tree->create<int>( + "rx_codecs" / _radio_slot / "gains"); // phony property so this dir exists + _tree->create<int>( + "tx_codecs" / _radio_slot / "gains"); // phony property so this dir exists _tree->create<std::string>("rx_codecs" / _radio_slot / "name").set("ads62p48"); _tree->create<std::string>("tx_codecs" / _radio_slot / "name").set("ad9146"); - _tree->create<meta_range_t>("rx_codecs" / _radio_slot / "gains" / "digital" / "range").set(meta_range_t(0, 6.0, 0.5)); + _tree->create<meta_range_t>("rx_codecs" / _radio_slot / "gains" / "digital" / "range") + .set(meta_range_t(0, 6.0, 0.5)); _tree->create<double>("rx_codecs" / _radio_slot / "gains" / "digital" / "value") - .add_coerced_subscriber(boost::bind(&x300_adc_ctrl::set_gain, _adc, _1)).set(0) - ; + .add_coerced_subscriber(boost::bind(&x300_adc_ctrl::set_gain, _adc, _1)) + .set(0); //////////////////////////////////////////////////////////////// // create front-end objects //////////////////////////////////////////////////////////////// for (size_t i = 0; i < _get_num_radios(); i++) { - _leds[i] = gpio_atr::gpio_atr_3000::make_write_only(_get_ctrl(i), regs::sr_addr(regs::LEDS)); - _leds[i]->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); + _leds[i] = gpio_atr::gpio_atr_3000::make_write_only( + _get_ctrl(i), regs::sr_addr(regs::LEDS)); + _leds[i]->set_atr_mode( + usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); - _rx_fe_map[i].core = rx_frontend_core_3000::make(_get_ctrl(i), regs::sr_addr(x300_regs::RX_FE_BASE)); + _rx_fe_map[i].core = rx_frontend_core_3000::make( + _get_ctrl(i), regs::sr_addr(x300_regs::RX_FE_BASE)); _rx_fe_map[i].core->set_adc_rate(_radio_clk_rate); _rx_fe_map[i].core->set_dc_offset(rx_frontend_core_3000::DEFAULT_DC_OFFSET_VALUE); - _rx_fe_map[i].core->set_dc_offset_auto(rx_frontend_core_3000::DEFAULT_DC_OFFSET_ENABLE); - _rx_fe_map[i].core->populate_subtree(_tree->subtree(_root_path / "rx_fe_corrections" / i)); + _rx_fe_map[i].core->set_dc_offset_auto( + rx_frontend_core_3000::DEFAULT_DC_OFFSET_ENABLE); + _rx_fe_map[i].core->populate_subtree( + _tree->subtree(_root_path / "rx_fe_corrections" / i)); - _tx_fe_map[i].core = tx_frontend_core_200::make(_get_ctrl(i), regs::sr_addr(x300_regs::TX_FE_BASE)); + _tx_fe_map[i].core = tx_frontend_core_200::make( + _get_ctrl(i), regs::sr_addr(x300_regs::TX_FE_BASE)); _tx_fe_map[i].core->set_dc_offset(tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE); - _tx_fe_map[i].core->set_iq_balance(tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE); - _tx_fe_map[i].core->populate_subtree(_tree->subtree(_root_path / "tx_fe_corrections" / i)); + _tx_fe_map[i].core->set_iq_balance( + tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE); + _tx_fe_map[i].core->populate_subtree( + _tree->subtree(_root_path / "tx_fe_corrections" / i)); //////////////////////////////////////////////////////////////// // Bind the daughterboard command time to the motherboard level property @@ -152,16 +168,19 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl) if (_tree->exists(fs_path("time") / "cmd")) { _tree->access<time_spec_t>(fs_path("time") / "cmd") - .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i)); + .add_coerced_subscriber( + boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i)); } } //////////////////////////////////////////////////////////////// // Update default SPP (overwrites the default value from the XML file) //////////////////////////////////////////////////////////////// - const size_t max_bytes_header = uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); - const size_t default_spp = (_tree->access<size_t>("mtu/recv").get() - max_bytes_header) - / (2 * sizeof(int16_t)); + const size_t max_bytes_header = + uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); + const size_t default_spp = + (_tree->access<size_t>("mtu/recv").get() - max_bytes_header) + / (2 * sizeof(int16_t)); _tree->access<int>(get_arg_path("spp") / "value").set(default_spp); } @@ -173,21 +192,19 @@ x300_radio_ctrl_impl::~x300_radio_ctrl_impl() _tree->remove(fs_path("tx_codecs" / _radio_slot)); _tree->remove(_root_path / "rx_fe_corrections"); _tree->remove(_root_path / "tx_fe_corrections"); - if (_radio_type==PRIMARY) { - for(const gpio_atr::gpio_attr_map_t::value_type attr: gpio_atr::gpio_attr_map) { + if (_radio_type == PRIMARY) { + for (const gpio_atr::gpio_attr_map_t::value_type attr : + gpio_atr::gpio_attr_map) { _tree->remove(fs_path("gpio") / "FP0" / attr.second); } } // Reset peripherals - if (_radio_type==PRIMARY) { + if (_radio_type == PRIMARY) { _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1); _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0); - } - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0); - _regs->misc_outs_reg.flush(); - ) - + } _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0); + _regs->misc_outs_reg.flush();) } /**************************************************************************** @@ -197,102 +214,129 @@ double x300_radio_ctrl_impl::set_rate(double rate) { const double actual_rate = get_rate(); if (not uhd::math::frequencies_are_equal(rate, actual_rate)) { - UHD_LOGGER_WARNING("X300 RADIO") << "Requesting invalid sampling rate from device: " << rate/1e6 << " MHz. Actual rate is: " << actual_rate/1e6 << " MHz." ; + UHD_LOGGER_WARNING("X300 RADIO") + << "Requesting invalid sampling rate from device: " << rate / 1e6 + << " MHz. Actual rate is: " << actual_rate / 1e6 << " MHz."; } // On X3x0, tick rate can't actually be changed at runtime return actual_rate; } -void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t &time, const size_t chan) +void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t& time, const size_t chan) { - if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) { - _tree->access<time_spec_t>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd") - ).set(time); + if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) { + _tree + ->access<time_spec_t>( + fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd")) + .set(time); } } -void x300_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan) +void x300_radio_ctrl_impl::set_tx_antenna(const std::string& ant, const size_t chan) { - _tree->access<std::string>( - fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value") - ).set(ant); + _tree + ->access<std::string>( + fs_path("dboards" / _radio_slot / "tx_frontends" + / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value")) + .set(ant); } std::string x300_radio_ctrl_impl::get_tx_antenna(const size_t chan) { - return _tree->access<std::string>( - fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value") - ).get(); + return _tree + ->access<std::string>( + fs_path("dboards" / _radio_slot / "tx_frontends" + / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value")) + .get(); } -void x300_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t chan) +void x300_radio_ctrl_impl::set_rx_antenna(const std::string& ant, const size_t chan) { - _tree->access<std::string>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value") - ).set(ant); + _tree + ->access<std::string>( + fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value")) + .set(ant); } std::string x300_radio_ctrl_impl::get_rx_antenna(const size_t chan) { - return _tree->access<std::string>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value") - ).get(); + return _tree + ->access<std::string>( + fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value")) + .get(); } double x300_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan) { - return _tree->access<double>( - fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "freq" / "value") - ).set(freq).get(); + return _tree + ->access<double>(fs_path("dboards" / _radio_slot / "tx_frontends" + / _tx_fe_map.at(chan).db_fe_name / "freq" / "value")) + .set(freq) + .get(); } double x300_radio_ctrl_impl::get_tx_frequency(const size_t chan) { - return _tree->access<double>( - fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "freq" / "value") - ).get(); + return _tree + ->access<double>(fs_path("dboards" / _radio_slot / "tx_frontends" + / _tx_fe_map.at(chan).db_fe_name / "freq" / "value")) + .get(); } double x300_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan) { - return _tree->access<double>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "freq" / "value") - ).set(freq).get(); + return _tree + ->access<double>(fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "freq" / "value")) + .set(freq) + .get(); } double x300_radio_ctrl_impl::get_rx_frequency(const size_t chan) { - return _tree->access<double>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "freq" / "value") - ).get(); + return _tree + ->access<double>(fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "freq" / "value")) + .get(); } double x300_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan) { - return _tree->access<double>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value") - ).set(bandwidth).get(); + return _tree + ->access<double>( + fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value")) + .set(bandwidth) + .get(); } double x300_radio_ctrl_impl::get_rx_bandwidth(const size_t chan) { - return _tree->access<double>( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value") - ).get(); + return _tree + ->access<double>( + fs_path("dboards" / _radio_slot / "rx_frontends" + / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value")) + .get(); } double x300_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan) { - //TODO: This is extremely hacky! - fs_path path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "gains"); + // TODO: This is extremely hacky! + fs_path path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name + / "gains"); std::vector<std::string> gain_stages = _tree->list(path); if (gain_stages.size() == 1) { - const double actual_gain = _tree->access<double>(path / gain_stages[0] / "value").set(gain).get(); + const double actual_gain = + _tree->access<double>(path / gain_stages[0] / "value").set(gain).get(); radio_ctrl_impl::set_tx_gain(actual_gain, chan); return gain; } else { - UHD_LOGGER_WARNING("X300 RADIO") << "set_tx_gain: could not apply gain for this daughterboard."; + UHD_LOGGER_WARNING("X300 RADIO") + << "set_tx_gain: could not apply gain for this daughterboard."; radio_ctrl_impl::set_tx_gain(0.0, chan); return 0.0; } @@ -300,15 +344,18 @@ double x300_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan) double x300_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan) { - //TODO: This is extremely hacky! - fs_path path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "gains"); + // TODO: This is extremely hacky! + fs_path path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name + / "gains"); std::vector<std::string> gain_stages = _tree->list(path); if (gain_stages.size() == 1) { - const double actual_gain = _tree->access<double>(path / gain_stages[0] / "value").set(gain).get(); + const double actual_gain = + _tree->access<double>(path / gain_stages[0] / "value").set(gain).get(); radio_ctrl_impl::set_rx_gain(actual_gain, chan); return gain; } else { - UHD_LOGGER_WARNING("X300 RADIO") << "set_rx_gain: could not apply gain for this daughterboard."; + UHD_LOGGER_WARNING("X300 RADIO") + << "set_rx_gain: could not apply gain for this daughterboard."; radio_ctrl_impl::set_tx_gain(0.0, chan); return 0.0; } @@ -317,79 +364,105 @@ double x300_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan) std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_names(const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); std::vector<std::string> lo_names; if (_tree->exists(rx_fe_fe_root / "los")) { - for(const std::string &name: _tree->list(rx_fe_fe_root / "los")) { + for (const std::string& name : _tree->list(rx_fe_fe_root / "los")) { lo_names.push_back(name); } } return lo_names; } -std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_sources(const std::string &name, const size_t chan) +std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_sources( + const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - return _tree->access< std::vector<std::string> >(rx_fe_fe_root / "los" / ALL_LOS / "source" / "options").get(); + // Special value ALL_LOS support atomically sets the source for all LOs + return _tree + ->access<std::vector<std::string>>( + rx_fe_fe_root / "los" / ALL_LOS / "source" / "options") + .get(); } else { return std::vector<std::string>(); } } else { if (_tree->exists(rx_fe_fe_root / "los")) { - return _tree->access< std::vector<std::string> >(rx_fe_fe_root / "los" / name / "source" / "options").get(); + return _tree + ->access<std::vector<std::string>>( + rx_fe_fe_root / "los" / name / "source" / "options") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { // If the daughterboard doesn't expose it's LO(s) then it can only be internal - return std::vector<std::string> (1, "internal"); + return std::vector<std::string>(1, "internal"); } } -void x300_radio_ctrl_impl::set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan) +void x300_radio_ctrl_impl::set_rx_lo_source( + const std::string& src, const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - _tree->access<std::string>(rx_fe_fe_root / "los" / ALL_LOS / "source" / "value").set(src); + // Special value ALL_LOS support atomically sets the source for all LOs + _tree + ->access<std::string>( + rx_fe_fe_root / "los" / ALL_LOS / "source" / "value") + .set(src); } else { - for(const std::string &n: _tree->list(rx_fe_fe_root / "los")) { + for (const std::string& n : _tree->list(rx_fe_fe_root / "los")) { this->set_rx_lo_source(src, n, chan); } } } else { if (_tree->exists(rx_fe_fe_root / "los")) { - _tree->access<std::string>(rx_fe_fe_root / "los" / name / "source" / "value").set(src); + _tree + ->access<std::string>( + rx_fe_fe_root / "los" / name / "source" / "value") + .set(src); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } -const std::string x300_radio_ctrl_impl::get_rx_lo_source(const std::string &name, const size_t chan) +const std::string x300_radio_ctrl_impl::get_rx_lo_source( + const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { - //Special value ALL_LOS support atomically sets the source for all LOs - return _tree->access<std::string>(rx_fe_fe_root / "los" / ALL_LOS / "source" / "value").get(); + // Special value ALL_LOS support atomically sets the source for all LOs + return _tree + ->access<std::string>( + rx_fe_fe_root / "los" / ALL_LOS / "source" / "value") + .get(); } else { if (_tree->exists(rx_fe_fe_root / "los")) { - return _tree->access<std::string>(rx_fe_fe_root / "los" / name / "source" / "value").get(); + return _tree + ->access<std::string>( + rx_fe_fe_root / "los" / name / "source" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -400,17 +473,20 @@ const std::string x300_radio_ctrl_impl::get_rx_lo_source(const std::string &name } } -void x300_radio_ctrl_impl::set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan) +void x300_radio_ctrl_impl::set_rx_lo_export_enabled( + bool enabled, const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) { - //Special value ALL_LOS support atomically sets the source for all LOs - _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").set(enabled); + // Special value ALL_LOS support atomically sets the source for all LOs + _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export") + .set(enabled); } else { - for(const std::string &n: _tree->list(rx_fe_fe_root / "los")) { + for (const std::string& n : _tree->list(rx_fe_fe_root / "los")) { this->set_rx_lo_export_enabled(enabled, n, chan); } } @@ -422,17 +498,20 @@ void x300_radio_ctrl_impl::set_rx_lo_export_enabled(bool enabled, const std::str } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } -bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(const std::string &name, const size_t chan) +bool x300_radio_ctrl_impl::get_rx_lo_export_enabled( + const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { - //Special value ALL_LOS support atomically sets the source for all LOs + // Special value ALL_LOS support atomically sets the source for all LOs return _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").get(); } else { if (_tree->exists(rx_fe_fe_root / "los")) { @@ -447,56 +526,73 @@ bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(const std::string &name, con } } -double x300_radio_ctrl_impl::set_rx_lo_freq(double freq, const std::string &name, const size_t chan) +double x300_radio_ctrl_impl::set_rx_lo_freq( + double freq, const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { - throw uhd::runtime_error("LO frequency must be set for each stage individually"); + throw uhd::runtime_error( + "LO frequency must be set for each stage individually"); } else { if (_tree->exists(rx_fe_fe_root / "los")) { - _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").set(freq); - return _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").get(); + _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value") + .set(freq); + return _tree + ->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { - throw uhd::runtime_error("This device does not support manual configuration of LOs"); + throw uhd::runtime_error( + "This device does not support manual configuration of LOs"); } } -double x300_radio_ctrl_impl::get_rx_lo_freq(const std::string &name, const size_t chan) +double x300_radio_ctrl_impl::get_rx_lo_freq(const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { - throw uhd::runtime_error("LO frequency must be retrieved for each stage individually"); + throw uhd::runtime_error( + "LO frequency must be retrieved for each stage individually"); } else { if (_tree->exists(rx_fe_fe_root / "los")) { - return _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").get(); + return _tree + ->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } } } else { // Return actual RF frequency if the daughterboard doesn't expose it's LO(s) - return _tree->access<double>(rx_fe_fe_root / "freq" /" value").get(); + return _tree->access<double>(rx_fe_fe_root / "freq" / " value").get(); } } -freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(const std::string &name, const size_t chan) +freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range( + const std::string& name, const size_t chan) { - fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); + fs_path rx_fe_fe_root = fs_path( + "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name); if (_tree->exists(rx_fe_fe_root / "los")) { if (name == ALL_LOS) { - throw uhd::runtime_error("LO frequency range must be retrieved for each stage individually"); + throw uhd::runtime_error( + "LO frequency range must be retrieved for each stage individually"); } else { if (_tree->exists(rx_fe_fe_root / "los")) { - return _tree->access<freq_range_t>(rx_fe_fe_root / "los" / name / "freq" / "range").get(); + return _tree + ->access<freq_range_t>( + rx_fe_fe_root / "los" / name / "freq" / "range") + .get(); } else { throw uhd::runtime_error("Could not find LO stage " + name); } @@ -508,21 +604,19 @@ freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(const std::string &name, } template <typename map_type> -static size_t _get_chan_from_map(std::map<size_t, map_type> map, const std::string &fe) +static size_t _get_chan_from_map(std::map<size_t, map_type> map, const std::string& fe) { for (auto it = map.begin(); it != map.end(); ++it) { if (it->second.db_fe_name == fe) { return it->first; } - } - throw uhd::runtime_error(str( - boost::format("Invalid daughterboard frontend name: %s") - % fe - )); + throw uhd::runtime_error( + str(boost::format("Invalid daughterboard frontend name: %s") % fe)); } -size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, const uhd::direction_t direction) +size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe( + const std::string& fe, const uhd::direction_t direction) { switch (direction) { case uhd::TX_DIRECTION: @@ -534,7 +628,8 @@ size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, cons } } -std::string x300_radio_ctrl_impl::get_dboard_fe_from_chan(const size_t chan, const uhd::direction_t direction) +std::string x300_radio_ctrl_impl::get_dboard_fe_from_chan( + const size_t chan, const uhd::direction_t direction) { switch (direction) { case uhd::TX_DIRECTION: @@ -565,61 +660,83 @@ double x300_radio_ctrl_impl::get_output_samp_rate(size_t chan) std::vector<std::string> x300_radio_ctrl_impl::get_gpio_banks() const { std::vector<std::string> banks{"RX", "TX"}; - // These pairs are the same, but RXA/TXA are from pre-rfnoc era and are kept for backward compat: - banks.push_back("RX"+_radio_slot); - banks.push_back("TX"+_radio_slot); + // These pairs are the same, but RXA/TXA are from pre-rfnoc era and are kept for + // backward compat: + banks.push_back("RX" + _radio_slot); + banks.push_back("TX" + _radio_slot); if (_fp_gpio) { banks.push_back("FP0"); } return banks; } -void x300_radio_ctrl_impl::set_gpio_attr( - const std::string &bank, - const std::string &attr, - const uint32_t value, - const uint32_t mask -) { +void x300_radio_ctrl_impl::set_gpio_attr(const std::string& bank, + const std::string& attr, + const uint32_t value, + const uint32_t mask) +{ if (bank == "FP0" and _fp_gpio) { - const uint32_t current = _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get(); + const uint32_t current = + _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get(); const uint32_t new_value = (current & ~mask) | (value & mask); _tree->access<uint32_t>(fs_path("gpio") / bank / attr).set(new_value); return; } - if (bank.size() > 2 and bank[1] == 'X') - { - const std::string name = bank.substr(2); - const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX; - dboard_iface::sptr iface = _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get(); - if (attr == "CTRL") iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask)); - if (attr == "DDR") iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask)); - if (attr == "OUT") iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask)); - if (attr == "ATR_0X") iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask)); - if (attr == "ATR_RX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask)); - if (attr == "ATR_TX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask)); - if (attr == "ATR_XX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask)); + if (bank.size() > 2 and bank[1] == 'X') { + const std::string name = bank.substr(2); + const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX + : dboard_iface::UNIT_TX; + dboard_iface::sptr iface = + _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get(); + if (attr == "CTRL") + iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask)); + if (attr == "DDR") + iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask)); + if (attr == "OUT") + iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask)); + if (attr == "ATR_0X") + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask)); + if (attr == "ATR_RX") + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask)); + if (attr == "ATR_TX") + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask)); + if (attr == "ATR_XX") + iface->set_atr_reg( + unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask)); } } uint32_t x300_radio_ctrl_impl::get_gpio_attr( - const std::string &bank, - const std::string &attr -) { + const std::string& bank, const std::string& attr) +{ if (bank == "FP0" and _fp_gpio) { return uint32_t(_tree->access<uint64_t>(fs_path("gpio") / bank / attr).get()); } if (bank.size() > 2 and bank[1] == 'X') { - const std::string name = bank.substr(2); - const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX; - dboard_iface::sptr iface = _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get(); - if (attr == "CTRL") return iface->get_pin_ctrl(unit); - if (attr == "DDR") return iface->get_gpio_ddr(unit); - if (attr == "OUT") return iface->get_gpio_out(unit); - if (attr == "ATR_0X") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE); - if (attr == "ATR_RX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY); - if (attr == "ATR_TX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY); - if (attr == "ATR_XX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX); - if (attr == "READBACK") return iface->read_gpio(unit); + const std::string name = bank.substr(2); + const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX + : dboard_iface::UNIT_TX; + dboard_iface::sptr iface = + _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get(); + if (attr == "CTRL") + return iface->get_pin_ctrl(unit); + if (attr == "DDR") + return iface->get_gpio_ddr(unit); + if (attr == "OUT") + return iface->get_gpio_out(unit); + if (attr == "ATR_0X") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE); + if (attr == "ATR_RX") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY); + if (attr == "ATR_TX") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY); + if (attr == "ATR_XX") + return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX); + if (attr == "READBACK") + return iface->read_gpio(unit); } return 0; } @@ -627,11 +744,10 @@ uint32_t x300_radio_ctrl_impl::get_gpio_attr( /**************************************************************************** * Radio control and setup ***************************************************************************/ -void x300_radio_ctrl_impl::setup_radio( - uhd::i2c_iface::sptr zpu_i2c, - x300_clock_ctrl::sptr clock, - bool ignore_cal_file, - bool verbose) +void x300_radio_ctrl_impl::setup_radio(uhd::i2c_iface::sptr zpu_i2c, + x300_clock_ctrl::sptr clock, + bool ignore_cal_file, + bool verbose) { _self_cal_adc_capture_delay(verbose); _ignore_cal_file = ignore_cal_file; @@ -644,57 +760,56 @@ void x300_radio_ctrl_impl::setup_radio( static const size_t TX_EEPROM_ADDR = 0x4; static const size_t GDB_EEPROM_ADDR = 0x1; const static std::vector<size_t> EEPROM_ADDRS{ - RX_EEPROM_ADDR, - TX_EEPROM_ADDR, - GDB_EEPROM_ADDR - }; + RX_EEPROM_ADDR, TX_EEPROM_ADDR, GDB_EEPROM_ADDR}; const static std::vector<std::string> EEPROM_PATHS{ - "rx_eeprom", - "tx_eeprom", - "gdb_eeprom" - }; + "rx_eeprom", "tx_eeprom", "gdb_eeprom"}; const size_t DB_OFFSET = (_radio_slot == "A") ? 0x0 : 0x2; - const fs_path db_path = ("dboards" / _radio_slot); + const fs_path db_path = ("dboards" / _radio_slot); for (size_t i = 0; i < EEPROM_ADDRS.size(); i++) { const size_t addr = EEPROM_ADDRS[i] + DB_OFFSET; - //Load EEPROM + // Load EEPROM _db_eeproms[addr].load(*zpu_i2c, BASE_ADDR | addr); - //Add to tree + // Add to tree _tree->create<dboard_eeprom_t>(db_path / EEPROM_PATHS[i]) .set(_db_eeproms[addr]) .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::_set_db_eeprom, - this, zpu_i2c, (BASE_ADDR | addr), _1)); + this, + zpu_i2c, + (BASE_ADDR | addr), + _1)); } - //create a new dboard interface + // create a new dboard interface x300_dboard_iface_config_t db_config; db_config.gpio = gpio_atr::db_gpio_atr_3000::make(_get_ctrl(IO_MASTER_RADIO), radio_ctrl_impl::regs::sr_addr(radio_ctrl_impl::regs::GPIO), - radio_ctrl_impl::regs::rb_addr(radio_ctrl_impl::regs::RB_DB_GPIO) - ); - db_config.spi = _spi; + radio_ctrl_impl::regs::rb_addr(radio_ctrl_impl::regs::RB_DB_GPIO)); + db_config.spi = _spi; db_config.rx_spi_slaveno = DB_RX_SEN; db_config.tx_spi_slaveno = DB_TX_SEN; - db_config.i2c = zpu_i2c; - db_config.clock = clock; - db_config.which_rx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_RX : X300_CLOCK_WHICH_DB1_RX; - db_config.which_tx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_TX : X300_CLOCK_WHICH_DB1_TX; - db_config.dboard_slot = (_radio_slot == "A")? 0 : 1; + db_config.i2c = zpu_i2c; + db_config.clock = clock; + db_config.which_rx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_RX + : X300_CLOCK_WHICH_DB1_RX; + db_config.which_tx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_TX + : X300_CLOCK_WHICH_DB1_TX; + db_config.dboard_slot = (_radio_slot == "A") ? 0 : 1; db_config.cmd_time_ctrl = _get_ctrl(IO_MASTER_RADIO); - //create a new dboard manager - boost::shared_ptr<x300_dboard_iface> db_iface = boost::make_shared<x300_dboard_iface>(db_config); - _db_manager = dboard_manager::make( - _db_eeproms[RX_EEPROM_ADDR + DB_OFFSET], + // create a new dboard manager + boost::shared_ptr<x300_dboard_iface> db_iface = + boost::make_shared<x300_dboard_iface>(db_config); + _db_manager = dboard_manager::make(_db_eeproms[RX_EEPROM_ADDR + DB_OFFSET], _db_eeproms[TX_EEPROM_ADDR + DB_OFFSET], _db_eeproms[GDB_EEPROM_ADDR + DB_OFFSET], - db_iface, _tree->subtree(db_path), + db_iface, + _tree->subtree(db_path), true // defer daughterboard intitialization ); size_t rx_chan = 0, tx_chan = 0; - for(const std::string& fe: _db_manager->get_rx_frontends()) { + for (const std::string& fe : _db_manager->get_rx_frontends()) { if (rx_chan >= _get_num_radios()) { break; } @@ -702,12 +817,14 @@ void x300_radio_ctrl_impl::setup_radio( db_iface->add_rx_fe(fe, _rx_fe_map[rx_chan].core); const fs_path fe_path(db_path / "rx_frontends" / fe); const std::string conn = _tree->access<std::string>(fe_path / "connection").get(); - const double if_freq = (_tree->exists(fe_path / "if_freq/value")) ? - _tree->access<double>(fe_path / "if_freq/value").get() : 0.0; + const double if_freq = + (_tree->exists(fe_path / "if_freq/value")) + ? _tree->access<double>(fe_path / "if_freq/value").get() + : 0.0; _rx_fe_map[rx_chan].core->set_fe_connection(usrp::fe_connection_t(conn, if_freq)); rx_chan++; } - for(const std::string& fe: _db_manager->get_tx_frontends()) { + for (const std::string& fe : _db_manager->get_tx_frontends()) { if (tx_chan >= _get_num_radios()) { break; } @@ -722,40 +839,63 @@ void x300_radio_ctrl_impl::setup_radio( // Initialize the daughterboards now that frontend cores and connections exist _db_manager->initialize_dboards(); - //now that dboard is created -- register into rx antenna event + // now that dboard is created -- register into rx antenna event if (not _rx_fe_map.empty()) { for (size_t i = 0; i < _get_num_radios(); i++) { - if (_tree->exists(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value")) { - // We need a desired subscriber for antenna/value because the experts don't coerce that property. - _tree->access<std::string>(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value") - .add_desired_subscriber(boost::bind(&x300_radio_ctrl_impl::_update_atr_leds, this, _1, i)); - _update_atr_leds(_tree->access<std::string> - (db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value").get(), i); + if (_tree->exists(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name + / "antenna" / "value")) { + // We need a desired subscriber for antenna/value because the experts + // don't coerce that property. + _tree + ->access<std::string>(db_path / "rx_frontends" + / _rx_fe_map[i].db_fe_name / "antenna" + / "value") + .add_desired_subscriber(boost::bind( + &x300_radio_ctrl_impl::_update_atr_leds, this, _1, i)); + _update_atr_leds(_tree + ->access<std::string>(db_path / "rx_frontends" + / _rx_fe_map[i].db_fe_name + / "antenna" / "value") + .get(), + i); } else { - _update_atr_leds("", i); //init anyway, even if never called + _update_atr_leds("", i); // init anyway, even if never called } } } - //bind frontend corrections to the dboard freq props + // bind frontend corrections to the dboard freq props const fs_path db_tx_fe_path = db_path / "tx_frontends"; if (not _tx_fe_map.empty()) { for (size_t i = 0; i < _get_num_radios(); i++) { - if (_tree->exists(db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) { - _tree->access<double>(db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value") - .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections, this, db_path, - _root_path / "tx_fe_corrections" / _tx_fe_map[i].db_fe_name, _1)); + if (_tree->exists( + db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) { + _tree + ->access<double>( + db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value") + .add_coerced_subscriber( + boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections, + this, + db_path, + _root_path / "tx_fe_corrections" / _tx_fe_map[i].db_fe_name, + _1)); } } } const fs_path db_rx_fe_path = db_path / "rx_frontends"; if (not _rx_fe_map.empty()) { for (size_t i = 0; i < _get_num_radios(); i++) { - if (_tree->exists(db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) { - _tree->access<double>(db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value") - .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections, this, db_path, - _root_path / "rx_fe_corrections" / _tx_fe_map[i].db_fe_name, - _1)); + if (_tree->exists( + db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) { + _tree + ->access<double>( + db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value") + .add_coerced_subscriber( + boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections, + this, + db_path, + _root_path / "rx_fe_corrections" / _tx_fe_map[i].db_fe_name, + _1)); } } } @@ -764,7 +904,7 @@ void x300_radio_ctrl_impl::setup_radio( // Set tick rate //////////////////////////////////////////////////////////////// const double tick_rate = get_output_samp_rate(0); - if (_radio_type==PRIMARY) { + if (_radio_type == PRIMARY) { // Slot A is the highlander timekeeper _tree->access<double>("tick_rate").set(tick_rate); } @@ -772,20 +912,16 @@ void x300_radio_ctrl_impl::setup_radio( } void x300_radio_ctrl_impl::set_rx_fe_corrections( - const fs_path &db_path, - const fs_path &rx_fe_corr_path, - const double lo_freq -) { + const fs_path& db_path, const fs_path& rx_fe_corr_path, const double lo_freq) +{ if (not _ignore_cal_file) { apply_rx_fe_corrections(_tree, db_path, rx_fe_corr_path, lo_freq); } } void x300_radio_ctrl_impl::set_tx_fe_corrections( - const fs_path &db_path, - const fs_path &tx_fe_corr_path, - const double lo_freq -) { + const fs_path& db_path, const fs_path& tx_fe_corr_path, const double lo_freq) +{ if (not _ignore_cal_file) { apply_tx_fe_corrections(_tree, db_path, tx_fe_corr_path, lo_freq); } @@ -793,7 +929,7 @@ void x300_radio_ctrl_impl::set_tx_fe_corrections( void x300_radio_ctrl_impl::reset_codec() { - if (_radio_type==PRIMARY) { //ADC/DAC reset lines only exist in Radio0 + if (_radio_type == PRIMARY) { // ADC/DAC reset lines only exist in Radio0 _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1); _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0); _regs->misc_outs_reg.flush(); @@ -809,29 +945,34 @@ void x300_radio_ctrl_impl::reset_codec() void x300_radio_ctrl_impl::self_test_adc(uint32_t ramp_time_ms) { - //Bypass all front-end corrections + // Bypass all front-end corrections for (size_t i = 0; i < _get_num_radios(); i++) { _rx_fe_map[i].core->bypass_all(true); } - //Test basic patterns - _adc->set_test_word("ones", "ones"); _check_adc(0xfffcfffc); - _adc->set_test_word("zeros", "zeros"); _check_adc(0x00000000); - _adc->set_test_word("ones", "zeros"); _check_adc(0xfffc0000); - _adc->set_test_word("zeros", "ones"); _check_adc(0x0000fffc); + // Test basic patterns + _adc->set_test_word("ones", "ones"); + _check_adc(0xfffcfffc); + _adc->set_test_word("zeros", "zeros"); + _check_adc(0x00000000); + _adc->set_test_word("ones", "zeros"); + _check_adc(0xfffc0000); + _adc->set_test_word("zeros", "ones"); + _check_adc(0x0000fffc); for (size_t k = 0; k < 14; k++) { _adc->set_test_word("zeros", "custom", 1 << k); - _check_adc(1 << (k+2)); + _check_adc(1 << (k + 2)); } for (size_t k = 0; k < 14; k++) { _adc->set_test_word("custom", "zeros", 1 << k); - _check_adc(1 << (k+18)); + _check_adc(1 << (k + 18)); } - //Turn on ramp pattern test + // Turn on ramp pattern test _adc->set_test_word("ramp", "ramp"); _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); - //Sleep added for SPI transactions to finish and ramp to start before checker is enabled. + // Sleep added for SPI transactions to finish and ramp to start before checker is + // enabled. std::this_thread::sleep_for(std::chrono::microseconds(1000)); _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); @@ -855,37 +996,46 @@ void x300_radio_ctrl_impl::self_test_adc(uint32_t ramp_time_ms) else q_status = "Not Locked!"; - //Return to normal mode + // Return to normal mode _adc->set_test_word("normal", "normal"); if ((i_status != "Good") or (q_status != "Good")) { throw uhd::runtime_error( - (boost::format("ADC self-test failed for %s. Ramp checker status: {ADC_A=%s, ADC_B=%s}")%unique_id()%i_status%q_status).str()); + (boost::format( + "ADC self-test failed for %s. Ramp checker status: {ADC_A=%s, ADC_B=%s}") + % unique_id() % i_status % q_status) + .str()); } - //Restore front-end corrections + // Restore front-end corrections for (size_t i = 0; i < _get_num_radios(); i++) { _rx_fe_map[i].core->bypass_all(false); } } -void x300_radio_ctrl_impl::extended_adc_test(const std::vector<x300_radio_ctrl_impl::sptr>& radios, double duration_s) +void x300_radio_ctrl_impl::extended_adc_test( + const std::vector<x300_radio_ctrl_impl::sptr>& radios, double duration_s) { static const size_t SECS_PER_ITER = 5; - UHD_LOGGER_INFO("X300 RADIO") << boost::format("Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...") - % duration_s % SECS_PER_ITER; + UHD_LOGGER_INFO("X300 RADIO") + << boost::format( + "Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...") + % duration_s % SECS_PER_ITER; - size_t num_iters = static_cast<size_t>(ceil(duration_s/SECS_PER_ITER)); + size_t num_iters = static_cast<size_t>(ceil(duration_s / SECS_PER_ITER)); size_t num_failures = 0; for (size_t iter = 0; iter < num_iters; iter++) { - //Run self-test - UHD_LOGGER_INFO("X300 RADIO") << boost::format("Extended ADC Self-Test Iteration %06d... ") % (iter+1); + // Run self-test + UHD_LOGGER_INFO("X300 RADIO") + << boost::format("Extended ADC Self-Test Iteration %06d... ") % (iter + 1); try { for (size_t i = 0; i < radios.size(); i++) { - radios[i]->self_test_adc((SECS_PER_ITER*1000)/radios.size()); + radios[i]->self_test_adc((SECS_PER_ITER * 1000) / radios.size()); } - UHD_LOGGER_INFO("X300 RADIO") << boost::format("Extended ADC Self-Test Iteration %06d passed ") % (iter+1); - } catch(std::exception &e) { + UHD_LOGGER_INFO("X300 RADIO") + << boost::format("Extended ADC Self-Test Iteration %06d passed ") + % (iter + 1); + } catch (std::exception& e) { num_failures++; UHD_LOGGER_ERROR("X300 RADIO") << e.what(); } @@ -894,75 +1044,82 @@ void x300_radio_ctrl_impl::extended_adc_test(const std::vector<x300_radio_ctrl_i UHD_LOGGER_INFO("X300 RADIO") << "Extended ADC Self-Test PASSED"; } else { throw uhd::runtime_error( - (boost::format("Extended ADC Self-Test FAILED!!! (%d/%d failures)\n") % num_failures % num_iters).str()); + (boost::format("Extended ADC Self-Test FAILED!!! (%d/%d failures)\n") + % num_failures % num_iters) + .str()); } } -void x300_radio_ctrl_impl::synchronize_dacs(const std::vector<x300_radio_ctrl_impl::sptr>& radios) +void x300_radio_ctrl_impl::synchronize_dacs( + const std::vector<x300_radio_ctrl_impl::sptr>& radios) { - if (radios.size() < 2) return; //Nothing to synchronize + if (radios.size() < 2) + return; // Nothing to synchronize //**PRECONDITION** - //This function assumes that all the VITA times in "radios" are synchronized - //to a common reference. Currently, this function is called in get_tx_stream - //which also has the same precondition. + // This function assumes that all the VITA times in "radios" are synchronized + // to a common reference. Currently, this function is called in get_tx_stream + // which also has the same precondition. - //Get a rough estimate of the cumulative command latency + // Get a rough estimate of the cumulative command latency boost::posix_time::ptime t_start = boost::posix_time::microsec_clock::local_time(); for (size_t i = 0; i < radios.size(); i++) { - radios[i]->user_reg_read64(regs::RB_TIME_NOW); //Discard value. We are just timing the call + radios[i]->user_reg_read64( + regs::RB_TIME_NOW); // Discard value. We are just timing the call } boost::posix_time::time_duration t_elapsed = boost::posix_time::microsec_clock::local_time() - t_start; - //Add 100% of headroom + uncertainty to the command time - uint64_t t_sync_us = (t_elapsed.total_microseconds() * 2) + 16000 /*Scheduler latency*/; + // Add 100% of headroom + uncertainty to the command time + uint64_t t_sync_us = + (t_elapsed.total_microseconds() * 2) + 16000 /*Scheduler latency*/; std::string err_str; - //Try to sync 3 times before giving up - for (size_t attempt = 0; attempt < 3; attempt++) - { - try - { - //Reinitialize and resync all DACs + // Try to sync 3 times before giving up + for (size_t attempt = 0; attempt < 3; attempt++) { + try { + // Reinitialize and resync all DACs for (size_t i = 0; i < radios.size(); i++) { radios[i]->_dac->sync(); } - //Set tick rate and make sure FRAMEP/N is 0 + // Set tick rate and make sure FRAMEP/N is 0 for (size_t i = 0; i < radios.size(); i++) { - radios[i]->set_command_tick_rate(radios[i]->_radio_clk_rate, IO_MASTER_RADIO); - radios[i]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0); + radios[i]->set_command_tick_rate( + radios[i]->_radio_clk_rate, IO_MASTER_RADIO); + radios[i]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0); } - //Pick radios[0] as the time reference. - uhd::time_spec_t sync_time = - radios[0]->_time64->get_time_now() + uhd::time_spec_t(((double)t_sync_us)/1e6); + // Pick radios[0] as the time reference. + uhd::time_spec_t sync_time = radios[0]->_time64->get_time_now() + + uhd::time_spec_t(((double)t_sync_us) / 1e6); - //Send the sync command + // Send the sync command for (size_t i = 0; i < radios.size(); i++) { radios[i]->set_command_time(sync_time, IO_MASTER_RADIO); - //Arm FRAMEP/N sync pulse by asserting a rising edge - radios[i]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 1); + // Arm FRAMEP/N sync pulse by asserting a rising edge + radios[i]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 1); } - //Reset FRAMEP/N to 0 after 2 clock cycles + // Reset FRAMEP/N to 0 after 2 clock cycles for (size_t i = 0; i < radios.size(); i++) { - radios[i]->set_command_time(sync_time + (2.0 / radios[i]->_radio_clk_rate), IO_MASTER_RADIO); - radios[i]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0); + radios[i]->set_command_time( + sync_time + (2.0 / radios[i]->_radio_clk_rate), IO_MASTER_RADIO); + radios[i]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0); radios[i]->set_command_time(uhd::time_spec_t(0.0), IO_MASTER_RADIO); } - //Wait and check status + // Wait and check status std::this_thread::sleep_for(std::chrono::microseconds(t_sync_us)); for (size_t i = 0; i < radios.size(); i++) { radios[i]->_dac->verify_sync(); } return; - } - catch (const uhd::runtime_error &e) - { + } catch (const uhd::runtime_error& e) { err_str = e.what(); UHD_LOGGER_TRACE("X300 RADIO") << "Retrying DAC synchronization: " << err_str; } @@ -978,144 +1135,165 @@ double x300_radio_ctrl_impl::self_cal_adc_xfer_delay( { UHD_LOGGER_INFO("X300 RADIO") << "Running ADC transfer delay self-cal: "; - //Effective resolution of the self-cal. + // Effective resolution of the self-cal. static const size_t NUM_DELAY_STEPS = 100; - double master_clk_period = (1.0e9 / clock->get_master_clock_rate()); //in ns - double delay_start = 0.0; - double delay_range = 2 * master_clk_period; - double delay_incr = delay_range / NUM_DELAY_STEPS; + double master_clk_period = (1.0e9 / clock->get_master_clock_rate()); // in ns + double delay_start = 0.0; + double delay_range = 2 * master_clk_period; + double delay_incr = delay_range / NUM_DELAY_STEPS; double cached_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_ADC0); - double fpga_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_FPGA); + double fpga_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_FPGA); - //Iterate through several values of delays and measure ADC data integrity - std::vector< std::pair<double,bool> > results; + // Iterate through several values of delays and measure ADC data integrity + std::vector<std::pair<double, bool>> results; for (size_t i = 0; i < NUM_DELAY_STEPS; i++) { - //Delay the ADC clock (will set both Ch0 and Ch1 delays) - double delay = clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr*i + delay_start); + // Delay the ADC clock (will set both Ch0 and Ch1 delays) + double delay = + clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr * i + delay_start); wait_for_clk_locked(0.1); uint32_t err_code = 0; for (size_t r = 0; r < radios.size(); r++) { - //Test each channel (I and Q) individually so as to not accidentally trigger - //on the data from the other channel if there is a swap + // Test each channel (I and Q) individually so as to not accidentally trigger + // on the data from the other channel if there is a swap // -- Test I Channel -- - //Put ADC in ramp test mode. Tie the other channel to all ones. + // Put ADC in ramp test mode. Tie the other channel to all ones. radios[r]->_adc->set_test_word("ramp", "ones"); - //Turn on the pattern checker in the FPGA. It will lock when it sees a zero - //and count deviations from the expected value - radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); - radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); - //50ms @ 200MHz = 10 million samples + // Turn on the pattern checker in the FPGA. It will lock when it sees a zero + // and count deviations from the expected value + radios[r]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); + radios[r]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); + // 50ms @ 200MHz = 10 million samples std::this_thread::sleep_for(std::chrono::milliseconds(50)); - if (radios[r]->_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) { - err_code += radios[r]->_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR); + if (radios[r]->_regs->misc_ins_reg.read( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) { + err_code += radios[r]->_regs->misc_ins_reg.get( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR); } else { - err_code += 100; //Increment error code by 100 to indicate no lock + err_code += 100; // Increment error code by 100 to indicate no lock } // -- Test Q Channel -- - //Put ADC in ramp test mode. Tie the other channel to all ones. + // Put ADC in ramp test mode. Tie the other channel to all ones. radios[r]->_adc->set_test_word("ones", "ramp"); - //Turn on the pattern checker in the FPGA. It will lock when it sees a zero - //and count deviations from the expected value - radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); - radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); - //50ms @ 200MHz = 10 million samples + // Turn on the pattern checker in the FPGA. It will lock when it sees a zero + // and count deviations from the expected value + radios[r]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); + radios[r]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); + // 50ms @ 200MHz = 10 million samples std::this_thread::sleep_for(std::chrono::milliseconds(50)); - if (radios[r]->_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) { - err_code += radios[r]->_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR); + if (radios[r]->_regs->misc_ins_reg.read( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) { + err_code += radios[r]->_regs->misc_ins_reg.get( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR); } else { - err_code += 100; //Increment error code by 100 to indicate no lock + err_code += 100; // Increment error code by 100 to indicate no lock } } - //UHD_LOGGER_INFO("X300 RADIO") << (boost::format("XferDelay=%fns, Error=%d") % delay % err_code); - results.push_back(std::pair<double,bool>(delay, err_code==0)); + // UHD_LOGGER_INFO("X300 RADIO") << (boost::format("XferDelay=%fns, Error=%d") % + // delay % err_code); + results.push_back(std::pair<double, bool>(delay, err_code == 0)); } - //Calculate the valid window + // Calculate the valid window int win_start_idx = -1, win_stop_idx = -1, cur_start_idx = -1, cur_stop_idx = -1; for (size_t i = 0; i < results.size(); i++) { - std::pair<double,bool>& item = results[i]; - if (item.second) { //If data is stable - if (cur_start_idx == -1) { //This is the first window + std::pair<double, bool>& item = results[i]; + if (item.second) { // If data is stable + if (cur_start_idx == -1) { // This is the first window cur_start_idx = i; - cur_stop_idx = i; - } else { //We are extending the window + cur_stop_idx = i; + } else { // We are extending the window cur_stop_idx = i; } } else { - if (cur_start_idx == -1) { //We haven't yet seen valid data - //Do nothing - } else if (win_start_idx == -1) { //We passed the first valid window + if (cur_start_idx == -1) { // We haven't yet seen valid data + // Do nothing + } else if (win_start_idx == -1) { // We passed the first valid window win_start_idx = cur_start_idx; - win_stop_idx = cur_stop_idx; - } else { //Update cached window if current window is larger - double cur_win_len = results[cur_stop_idx].first - results[cur_start_idx].first; - double cached_win_len = results[win_stop_idx].first - results[win_start_idx].first; + win_stop_idx = cur_stop_idx; + } else { // Update cached window if current window is larger + double cur_win_len = + results[cur_stop_idx].first - results[cur_start_idx].first; + double cached_win_len = + results[win_stop_idx].first - results[win_start_idx].first; if (cur_win_len > cached_win_len) { win_start_idx = cur_start_idx; - win_stop_idx = cur_stop_idx; + win_stop_idx = cur_stop_idx; } } - //Reset current window + // Reset current window cur_start_idx = -1; - cur_stop_idx = -1; + cur_stop_idx = -1; } } if (win_start_idx == -1) { - throw uhd::runtime_error("self_cal_adc_xfer_delay: Self calibration failed. Convergence error."); + throw uhd::runtime_error( + "self_cal_adc_xfer_delay: Self calibration failed. Convergence error."); } - double win_center = (results[win_stop_idx].first + results[win_start_idx].first) / 2.0; + double win_center = + (results[win_stop_idx].first + results[win_start_idx].first) / 2.0; double win_length = results[win_stop_idx].first - results[win_start_idx].first; - if (win_length < master_clk_period/4) { - throw uhd::runtime_error("self_cal_adc_xfer_delay: Self calibration failed. Valid window too narrow."); + if (win_length < master_clk_period / 4) { + throw uhd::runtime_error( + "self_cal_adc_xfer_delay: Self calibration failed. Valid window too narrow."); } - //Cycle slip the relative delay by a clock cycle to prevent sample misalignment - //fpga_clk_delay > 0 and 0 < win_center < 2*(1/MCR) so one cycle slip is all we need - bool cycle_slip = (win_center-fpga_clk_delay >= master_clk_period); + // Cycle slip the relative delay by a clock cycle to prevent sample misalignment + // fpga_clk_delay > 0 and 0 < win_center < 2*(1/MCR) so one cycle slip is all we need + bool cycle_slip = (win_center - fpga_clk_delay >= master_clk_period); if (cycle_slip) { win_center -= master_clk_period; } if (apply_delay) { - //Apply delay - win_center = clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, win_center); //Sets ADC0 and ADC1 + // Apply delay + win_center = clock->set_clock_delay( + X300_CLOCK_WHICH_ADC0, win_center); // Sets ADC0 and ADC1 wait_for_clk_locked(0.1); - //Validate + // Validate for (size_t r = 0; r < radios.size(); r++) { radios[r]->self_test_adc(2000); } } else { - //Restore delay - clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, cached_clk_delay); //Sets ADC0 and ADC1 + // Restore delay + clock->set_clock_delay( + X300_CLOCK_WHICH_ADC0, cached_clk_delay); // Sets ADC0 and ADC1 } - //Teardown + // Teardown for (size_t r = 0; r < radios.size(); r++) { radios[r]->_adc->set_test_word("normal", "normal"); - radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); + radios[r]->_regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); } - UHD_LOGGER_INFO("X300 RADIO") << (boost::format("ADC transfer delay self-cal done (FPGA->ADC=%.3fns%s, Window=%.3fns)") % - (win_center-fpga_clk_delay) % (cycle_slip?" +cyc":"") % win_length); + UHD_LOGGER_INFO("X300 RADIO") + << (boost::format( + "ADC transfer delay self-cal done (FPGA->ADC=%.3fns%s, Window=%.3fns)") + % (win_center - fpga_clk_delay) % (cycle_slip ? " +cyc" : "") + % win_length); return win_center; } /**************************************************************************** * Helpers ***************************************************************************/ -void x300_radio_ctrl_impl::_update_atr_leds(const std::string &rx_ant, const size_t chan) +void x300_radio_ctrl_impl::_update_atr_leds(const std::string& rx_ant, const size_t chan) { // The "RX1" port is used by TwinRX and the "TX/RX" port is used by all // other full-duplex dboards. We need to handle both here. const bool is_txrx = (rx_ant == "TX/RX" or rx_ant == "RX1"); - const int TXRX_RX = (1 << 0); - const int TXRX_TX = (1 << 1); - const int RX2_RX = (1 << 2); + const int TXRX_RX = (1 << 0); + const int TXRX_TX = (1 << 1); + const int RX2_RX = (1 << 2); _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_IDLE, 0); _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, is_txrx ? TXRX_RX : RX2_RX); _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, TXRX_TX); @@ -1124,76 +1302,91 @@ void x300_radio_ctrl_impl::_update_atr_leds(const std::string &rx_ant, const siz void x300_radio_ctrl_impl::_self_cal_adc_capture_delay(bool print_status) { - if (print_status) UHD_LOGGER_INFO("X300 RADIO") << "Running ADC capture delay self-cal..."; + if (print_status) + UHD_LOGGER_INFO("X300 RADIO") << "Running ADC capture delay self-cal..."; - static const uint32_t NUM_DELAY_STEPS = 32; //The IDELAYE2 element has 32 steps - static const uint32_t NUM_RETRIES = 2; //Retry self-cal if it fails in warmup situations - static const int32_t MIN_WINDOW_LEN = 4; + static const uint32_t NUM_DELAY_STEPS = 32; // The IDELAYE2 element has 32 steps + static const uint32_t NUM_RETRIES = + 2; // Retry self-cal if it fails in warmup situations + static const int32_t MIN_WINDOW_LEN = 4; int32_t win_start = -1, win_stop = -1; uint32_t iter = 0; while (iter++ < NUM_RETRIES) { for (uint32_t dly_tap = 0; dly_tap < NUM_DELAY_STEPS; dly_tap++) { - //Apply delay - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap); - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1); - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0); + // Apply delay + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap); + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1); + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0); uint32_t err_code = 0; // -- Test I Channel -- - //Put ADC in ramp test mode. Tie the other channel to all ones. + // Put ADC in ramp test mode. Tie the other channel to all ones. _adc->set_test_word("ramp", "ones"); - //Turn on the pattern checker in the FPGA. It will lock when it sees a zero - //and count deviations from the expected value - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); - //5ms @ 200MHz = 1 million samples + // Turn on the pattern checker in the FPGA. It will lock when it sees a zero + // and count deviations from the expected value + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); + // 5ms @ 200MHz = 1 million samples std::this_thread::sleep_for(std::chrono::milliseconds(5)); - if (_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) { - err_code += _regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR); + if (_regs->misc_ins_reg.read( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) { + err_code += _regs->misc_ins_reg.get( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR); } else { - err_code += 100; //Increment error code by 100 to indicate no lock + err_code += 100; // Increment error code by 100 to indicate no lock } // -- Test Q Channel -- - //Put ADC in ramp test mode. Tie the other channel to all ones. + // Put ADC in ramp test mode. Tie the other channel to all ones. _adc->set_test_word("ones", "ramp"); - //Turn on the pattern checker in the FPGA. It will lock when it sees a zero - //and count deviations from the expected value - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); - //5ms @ 200MHz = 1 million samples + // Turn on the pattern checker in the FPGA. It will lock when it sees a zero + // and count deviations from the expected value + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1); + // 5ms @ 200MHz = 1 million samples std::this_thread::sleep_for(std::chrono::milliseconds(5)); - if (_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) { - err_code += _regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR); + if (_regs->misc_ins_reg.read( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) { + err_code += _regs->misc_ins_reg.get( + radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR); } else { - err_code += 100; //Increment error code by 100 to indicate no lock + err_code += 100; // Increment error code by 100 to indicate no lock } if (err_code == 0) { - if (win_start == -1) { //This is the first window + if (win_start == -1) { // This is the first window win_start = dly_tap; - win_stop = dly_tap; - } else { //We are extending the window + win_stop = dly_tap; + } else { // We are extending the window win_stop = dly_tap; } } else { - if (win_start != -1) { //A valid window turned invalid + if (win_start != -1) { // A valid window turned invalid if (win_stop - win_start >= MIN_WINDOW_LEN) { - break; //Valid window found + break; // Valid window found } else { - win_start = -1; //Reset window + win_start = -1; // Reset window } } } - //UHD_LOGGER_INFO("X300 RADIO") << (boost::format("CapTap=%d, Error=%d") % dly_tap % err_code); + // UHD_LOGGER_INFO("X300 RADIO") << (boost::format("CapTap=%d, Error=%d") % + // dly_tap % err_code); } - //Retry the self-cal if it fails - if ((win_start == -1 || (win_stop - win_start) < MIN_WINDOW_LEN) && iter < NUM_RETRIES /*not last iteration*/) { + // Retry the self-cal if it fails + if ((win_start == -1 || (win_stop - win_start) < MIN_WINDOW_LEN) + && iter < NUM_RETRIES /*not last iteration*/) { win_start = -1; - win_stop = -1; + win_stop = -1; std::this_thread::sleep_for(std::chrono::milliseconds(2000)); } else { break; @@ -1203,46 +1396,55 @@ void x300_radio_ctrl_impl::_self_cal_adc_capture_delay(bool print_status) _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0); if (win_start == -1) { - throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. Convergence error."); + throw uhd::runtime_error( + "self_cal_adc_capture_delay: Self calibration failed. Convergence error."); } - if (win_stop-win_start < MIN_WINDOW_LEN) { - throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. Valid window too narrow."); + if (win_stop - win_start < MIN_WINDOW_LEN) { + throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. " + "Valid window too narrow."); } uint32_t ideal_tap = (win_stop + win_start) / 2; - _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap); + _regs->misc_outs_reg.write( + radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap); _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1); _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0); if (print_status) { - double tap_delay = (1.0e12 / _radio_clk_rate) / (2*32); //in ps - UHD_LOGGER_INFO("X300 RADIO") << boost::format("ADC capture delay self-cal done (Tap=%d, Window=%d, TapDelay=%.3fps, Iter=%d)") % ideal_tap % (win_stop-win_start) % tap_delay % iter; + double tap_delay = (1.0e12 / _radio_clk_rate) / (2 * 32); // in ps + UHD_LOGGER_INFO("X300 RADIO") + << boost::format("ADC capture delay self-cal done (Tap=%d, Window=%d, " + "TapDelay=%.3fps, Iter=%d)") + % ideal_tap % (win_stop - win_start) % tap_delay % iter; } } void x300_radio_ctrl_impl::_check_adc(const uint32_t val) { - //Wait for previous control transaction to flush + // Wait for previous control transaction to flush user_reg_read64(regs::RB_TEST); - //Wait for ADC test pattern to propagate + // Wait for ADC test pattern to propagate std::this_thread::sleep_for(std::chrono::microseconds(5)); - //Read value of RX readback register and verify - uint32_t adc_rb = static_cast<uint32_t>(user_reg_read64(regs::RB_TEST)>>32); - adc_rb ^= 0xfffc0000; //adapt for I inversion in FPGA + // Read value of RX readback register and verify + uint32_t adc_rb = static_cast<uint32_t>(user_reg_read64(regs::RB_TEST) >> 32); + adc_rb ^= 0xfffc0000; // adapt for I inversion in FPGA if (val != adc_rb) { throw uhd::runtime_error( - (boost::format("ADC self-test failed for %s. (Exp=0x%x, Got=0x%x)")%unique_id()%val%adc_rb).str()); + (boost::format("ADC self-test failed for %s. (Exp=0x%x, Got=0x%x)") + % unique_id() % val % adc_rb) + .str()); } } -void x300_radio_ctrl_impl::_set_db_eeprom(i2c_iface::sptr i2c, const size_t addr, const uhd::usrp::dboard_eeprom_t &db_eeprom) +void x300_radio_ctrl_impl::_set_db_eeprom( + i2c_iface::sptr i2c, const size_t addr, const uhd::usrp::dboard_eeprom_t& db_eeprom) { db_eeprom.store(*i2c, addr); _db_eeproms[addr] = db_eeprom; } -void x300_radio_ctrl_impl::_set_command_time(const time_spec_t &spec, const size_t port) +void x300_radio_ctrl_impl::_set_command_time(const time_spec_t& spec, const size_t port) { set_fe_cmd_time(spec, port); } @@ -1251,15 +1453,16 @@ void x300_radio_ctrl_impl::_set_command_time(const time_spec_t &spec, const size ***************************************************************************/ bool x300_radio_ctrl_impl::check_radio_config() { - UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::check_radio_config() " ; + UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::check_radio_config() "; const fs_path rx_fe_path = fs_path("dboards" / _radio_slot / "rx_frontends"); for (size_t chan = 0; chan < _num_rx_channels; chan++) { if (_tree->exists(rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled")) { const bool chan_active = _is_streamer_active(uhd::RX_DIRECTION, chan); if (chan_active) { - _tree->access<bool>(rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled") - .set(chan_active) - ; + _tree + ->access<bool>( + rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled") + .set(chan_active); } } } @@ -1269,9 +1472,10 @@ bool x300_radio_ctrl_impl::check_radio_config() if (_tree->exists(tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled")) { const bool chan_active = _is_streamer_active(uhd::TX_DIRECTION, chan); if (chan_active) { - _tree->access<bool>(tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled") - .set(chan_active) - ; + _tree + ->access<bool>( + tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled") + .set(chan_active); } } } diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp index 7b02f2cf1..7cc0ea18d 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP #define INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP -#include "x300_clock_ctrl.hpp" #include "x300_adc_ctrl.hpp" +#include "x300_clock_ctrl.hpp" #include "x300_dac_ctrl.hpp" #include "x300_regs.hpp" #include <uhd/usrp/dboard_eeprom.hpp> @@ -17,11 +17,10 @@ #include <uhd/usrp/gpio_defs.hpp> #include <uhdlib/rfnoc/radio_ctrl_impl.hpp> #include <uhdlib/usrp/cores/rx_frontend_core_3000.hpp> -#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> #include <uhdlib/usrp/cores/spi_core_3000.hpp> +#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp> -namespace uhd { - namespace rfnoc { +namespace uhd { namespace rfnoc { /*! \brief Provide access to an X300 radio. */ @@ -41,8 +40,8 @@ public: ***********************************************************************/ double set_rate(double rate); - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); std::string get_tx_antenna(const size_t chan); std::string get_rx_antenna(const size_t chan); @@ -57,24 +56,30 @@ public: double set_rx_gain(const double gain, const size_t chan); std::vector<std::string> get_rx_lo_names(const size_t chan); - std::vector<std::string> get_rx_lo_sources(const std::string &name, const size_t chan); - freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan); + std::vector<std::string> get_rx_lo_sources( + const std::string& name, const size_t chan); + freq_range_t get_rx_lo_freq_range(const std::string& name, const size_t chan); - void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan); - const std::string get_rx_lo_source(const std::string &name, const size_t chan); + void set_rx_lo_source( + const std::string& src, const std::string& name, const size_t chan); + const std::string get_rx_lo_source(const std::string& name, const size_t chan); - void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan); - bool get_rx_lo_export_enabled(const std::string &name, const size_t chan); + void set_rx_lo_export_enabled( + bool enabled, const std::string& name, const size_t chan); + bool get_rx_lo_export_enabled(const std::string& name, const size_t chan); - double set_rx_lo_freq(double freq, const std::string &name, const size_t chan); - double get_rx_lo_freq(const std::string &name, const size_t chan); + double set_rx_lo_freq(double freq, const std::string& name, const size_t chan); + double get_rx_lo_freq(const std::string& name, const size_t chan); - size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir); + size_t get_chan_from_dboard_fe(const std::string& fe, const direction_t dir); std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir); std::vector<std::string> get_gpio_banks() const; - void set_gpio_attr(const std::string &bank, const std::string &attr, const uint32_t value, const uint32_t mask); - uint32_t get_gpio_attr(const std::string &bank, const std::string &attr); + void set_gpio_attr(const std::string& bank, + const std::string& attr, + const uint32_t value, + const uint32_t mask); + uint32_t get_gpio_attr(const std::string& bank, const std::string& attr); double get_output_samp_rate(size_t port); @@ -83,23 +88,19 @@ public: ***********************************************************************/ /*! Set up the radio. No API calls may be made before this one. */ - void setup_radio( - uhd::i2c_iface::sptr zpu_i2c, + void setup_radio(uhd::i2c_iface::sptr zpu_i2c, x300_clock_ctrl::sptr clock, bool ignore_cal_file, - bool verbose - ); + bool verbose); void reset_codec(); - void self_test_adc( - uint32_t ramp_time_ms = 100); + void self_test_adc(uint32_t ramp_time_ms = 100); static void extended_adc_test( const std::vector<x300_radio_ctrl_impl::sptr>&, double duration_s); - static void synchronize_dacs( - const std::vector<x300_radio_ctrl_impl::sptr>& radios); + static void synchronize_dacs(const std::vector<x300_radio_ctrl_impl::sptr>& radios); static double self_cal_adc_xfer_delay( const std::vector<x300_radio_ctrl_impl::sptr>& radios, @@ -111,21 +112,25 @@ protected: virtual bool check_radio_config(); private: - class radio_regmap_t : public uhd::soft_regmap_t { + class radio_regmap_t : public uhd::soft_regmap_t + { public: typedef boost::shared_ptr<radio_regmap_t> sptr; - class misc_outs_reg_t : public uhd::soft_reg32_wo_t { + class misc_outs_reg_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED, /*width*/ 1, /*shift*/ 0); //[0] - UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N, /*width*/ 1, /*shift*/ 1); //[1] - UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET, /*width*/ 1, /*shift*/ 2); //[2] - UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB, /*width*/ 1, /*shift*/ 3); //[3] - UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL, /*width*/ 5, /*shift*/ 4); //[8:4] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER_ENABLED, /*width*/ 1, /*shift*/ 9); //[9] - UHD_DEFINE_SOFT_REG_FIELD(DAC_SYNC, /*width*/ 1, /*shift*/ 10); //[10] - - misc_outs_reg_t(): uhd::soft_reg32_wo_t(regs::sr_addr(regs::MISC_OUTS)) { - //Initial values + UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED, /*width*/ 1, /*shift*/ 0); //[0] + UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N, /*width*/ 1, /*shift*/ 1); //[1] + UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET, /*width*/ 1, /*shift*/ 2); //[2] + UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB, /*width*/ 1, /*shift*/ 3); //[3] + UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL, /*width*/ 5, /*shift*/ 4); //[8:4] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER_ENABLED, /*width*/ 1, /*shift*/ 9); //[9] + UHD_DEFINE_SOFT_REG_FIELD(DAC_SYNC, /*width*/ 1, /*shift*/ 10); //[10] + + misc_outs_reg_t() : uhd::soft_reg32_wo_t(regs::sr_addr(regs::MISC_OUTS)) + { + // Initial values set(DAC_ENABLED, 0); set(DAC_RESET_N, 0); set(ADC_RESET, 0); @@ -136,77 +141,96 @@ private: } } misc_outs_reg; - class misc_ins_reg_t : public uhd::soft_reg64_ro_t { + class misc_ins_reg_t : public uhd::soft_reg64_ro_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 32); //[0] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 33); //[1] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 34); //[2] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 35); //[3] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_ERROR, /*width*/ 1, /*shift*/ 36); //[4] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_ERROR, /*width*/ 1, /*shift*/ 37); //[5] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_ERROR, /*width*/ 1, /*shift*/ 38); //[6] - UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_ERROR, /*width*/ 1, /*shift*/ 39); //[7] - - misc_ins_reg_t(): uhd::soft_reg64_ro_t(regs::rb_addr(regs::RB_MISC_IO)) { } + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 32); //[0] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 33); //[1] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 34); //[2] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 35); //[3] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER0_Q_ERROR, /*width*/ 1, /*shift*/ 36); //[4] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER0_I_ERROR, /*width*/ 1, /*shift*/ 37); //[5] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER1_Q_ERROR, /*width*/ 1, /*shift*/ 38); //[6] + UHD_DEFINE_SOFT_REG_FIELD( + ADC_CHECKER1_I_ERROR, /*width*/ 1, /*shift*/ 39); //[7] + + misc_ins_reg_t() : uhd::soft_reg64_ro_t(regs::rb_addr(regs::RB_MISC_IO)) {} } misc_ins_reg; - radio_regmap_t(int radio_num) : soft_regmap_t("radio" + std::to_string(radio_num) + "_regmap") { + radio_regmap_t(int radio_num) + : soft_regmap_t("radio" + std::to_string(radio_num) + "_regmap") + { add_to_map(misc_outs_reg, "misc_outs_reg", PRIVATE); add_to_map(misc_ins_reg, "misc_ins_reg", PRIVATE); } }; - struct x300_regs { - static const uint32_t TX_FE_BASE = 224; - static const uint32_t RX_FE_BASE = 232; + struct x300_regs + { + static const uint32_t TX_FE_BASE = 224; + static const uint32_t RX_FE_BASE = 232; }; - void _update_atr_leds(const std::string &rx_ant, const size_t chan); + void _update_atr_leds(const std::string& rx_ant, const size_t chan); void _self_cal_adc_capture_delay(bool print_status); void _check_adc(const uint32_t val); - void _set_db_eeprom(uhd::i2c_iface::sptr i2c, const size_t, const uhd::usrp::dboard_eeprom_t &); + void _set_db_eeprom( + uhd::i2c_iface::sptr i2c, const size_t, const uhd::usrp::dboard_eeprom_t&); - void set_rx_fe_corrections(const uhd::fs_path &db_path, const uhd::fs_path &rx_fe_corr_path, const double lo_freq); - void set_tx_fe_corrections(const uhd::fs_path &db_path, const uhd::fs_path &tx_fe_corr_path, const double lo_freq); + void set_rx_fe_corrections(const uhd::fs_path& db_path, + const uhd::fs_path& rx_fe_corr_path, + const double lo_freq); + void set_tx_fe_corrections(const uhd::fs_path& db_path, + const uhd::fs_path& tx_fe_corr_path, + const double lo_freq); - void _set_command_time(const uhd::time_spec_t &spec, const size_t port); - void set_fe_cmd_time(const time_spec_t &time, const size_t chan); + void _set_command_time(const uhd::time_spec_t& spec, const size_t port); + void set_fe_cmd_time(const time_spec_t& time, const size_t chan); private: // members enum radio_connection_t { PRIMARY, SECONDARY }; - radio_connection_t _radio_type; - std::string _radio_slot; + radio_connection_t _radio_type; + std::string _radio_slot; //! Radio clock rate is the rate at which the ADC and DAC are running at. // Not necessarily this block's sampling rate (tick rate). - double _radio_clk_rate; + double _radio_clk_rate; - radio_regmap_t::sptr _regs; - std::map<size_t, usrp::gpio_atr::gpio_atr_3000::sptr> _leds; - spi_core_3000::sptr _spi; - x300_adc_ctrl::sptr _adc; - x300_dac_ctrl::sptr _dac; - usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio; + radio_regmap_t::sptr _regs; + std::map<size_t, usrp::gpio_atr::gpio_atr_3000::sptr> _leds; + spi_core_3000::sptr _spi; + x300_adc_ctrl::sptr _adc; + x300_dac_ctrl::sptr _dac; + usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio; std::map<size_t, usrp::dboard_eeprom_t> _db_eeproms; - usrp::dboard_manager::sptr _db_manager; + usrp::dboard_manager::sptr _db_manager; - struct rx_fe_perif { - std::string name; - std::string db_fe_name; + struct rx_fe_perif + { + std::string name; + std::string db_fe_name; rx_frontend_core_3000::sptr core; }; - struct tx_fe_perif { - std::string name; - std::string db_fe_name; - tx_frontend_core_200::sptr core; + struct tx_fe_perif + { + std::string name; + std::string db_fe_name; + tx_frontend_core_200::sptr core; }; - std::map<size_t, rx_fe_perif> _rx_fe_map; - std::map<size_t, tx_fe_perif> _tx_fe_map; + std::map<size_t, rx_fe_perif> _rx_fe_map; + std::map<size_t, tx_fe_perif> _tx_fe_map; bool _ignore_cal_file; diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp index 5fdc89979..d2677c05e 100644 --- a/host/lib/usrp/x300/x300_regs.hpp +++ b/host/lib/usrp/x300/x300_regs.hpp @@ -9,22 +9,22 @@ #define INCLUDED_X300_REGS_HPP #include <uhd/config.hpp> -#include <stdint.h> #include <uhd/utils/soft_register.hpp> +#include <stdint.h> -static const int BL_ADDRESS = 0; -static const int BL_DATA = 1; +static const int BL_ADDRESS = 0; +static const int BL_DATA = 1; -//wishbone settings map - relevant to host code -#define SET0_BASE 0xa000 -#define SETXB_BASE 0xb000 +// wishbone settings map - relevant to host code +#define SET0_BASE 0xa000 +#define SETXB_BASE 0xb000 #define BOOT_LDR_BASE 0xfa00 -#define I2C0_BASE 0xfe00 -#define I2C1_BASE 0xff00 +#define I2C0_BASE 0xfe00 +#define I2C1_BASE 0xff00 #define SR_ADDR(base, offset) ((base) + (offset)*4) -//I2C1 device addresses -#define MBOARD_EEPROM_ADDR 0x50 +// I2C1 device addresses +#define MBOARD_EEPROM_ADDR 0x50 static const int ZPU_SR_LEDS = 00; static const int ZPU_SR_SW_RST = 01; @@ -37,11 +37,11 @@ static const int ZPU_SR_ETHINT1 = 56; static const int ZPU_SR_DRAM_FIFO0 = 72; static const int ZPU_SR_DRAM_FIFO1 = 80; -//reset bits -#define ZPU_SR_SW_RST_ETH_PHY (1<<0) -#define ZPU_SR_SW_RST_RADIO_RST (1<<1) -#define ZPU_SR_SW_RST_RADIO_CLK_PLL (1<<2) -#define ZPU_SR_SW_RST_ADC_IDELAYCTRL (1<<3) +// reset bits +#define ZPU_SR_SW_RST_ETH_PHY (1 << 0) +#define ZPU_SR_SW_RST_RADIO_RST (1 << 1) +#define ZPU_SR_SW_RST_RADIO_CLK_PLL (1 << 2) +#define ZPU_SR_SW_RST_ADC_IDELAYCTRL (1 << 3) static const int ZPU_RB_SPI = 2; static const int ZPU_RB_CLK_STATUS = 3; @@ -55,23 +55,23 @@ static const uint32_t RB_SFP_1G_ETH = 0; static const uint32_t RB_SFP_10G_ETH = 1; static const uint32_t RB_SFP_AURORA = 2; -//spi slaves on radio -#define DB_DAC_SEN (1 << 7) -#define DB_ADC_SEN (1 << 6) +// spi slaves on radio +#define DB_DAC_SEN (1 << 7) +#define DB_ADC_SEN (1 << 6) #define DB_RX_LSADC_SEN (1 << 5) #define DB_RX_LSDAC_SEN (1 << 4) #define DB_TX_LSADC_SEN (1 << 3) #define DB_TX_LSDAC_SEN (1 << 2) -#define DB_RX_SEN (1 << 1) -#define DB_TX_SEN (1 << 0) +#define DB_RX_SEN (1 << 1) +#define DB_TX_SEN (1 << 0) //------------------------------------------------------------------- // PCIe Registers //------------------------------------------------------------------- -static const uint32_t X300_PCIE_VID = 0x1093; -static const uint32_t X300_PCIE_PID = 0xC4C4; -//Rev 0-6 motherboard/PCIe IDs (ADC driven at 3.3V) +static const uint32_t X300_PCIE_VID = 0x1093; +static const uint32_t X300_PCIE_PID = 0xC4C4; +// Rev 0-6 motherboard/PCIe IDs (ADC driven at 3.3V) static const uint32_t X300_USRP_PCIE_SSID_ADC_33 = 0x7736; static const uint32_t X310_USRP_PCIE_SSID_ADC_33 = 0x76CA; static const uint32_t X310_2940R_40MHz_PCIE_SSID_ADC_33 = 0x772B; @@ -88,7 +88,7 @@ static const uint32_t X310_2952R_120MHz_PCIE_SSID_ADC_33 = 0x77FF; static const uint32_t X310_2953R_40MHz_PCIE_SSID_ADC_33 = 0x7731; static const uint32_t X310_2953R_120MHz_PCIE_SSID_ADC_33 = 0x7800; static const uint32_t X310_2954R_40MHz_PCIE_SSID_ADC_33 = 0x7732; -//Rev 7+ motherboard/PCIe IDs (ADCs driven at 1.8V) +// Rev 7+ motherboard/PCIe IDs (ADCs driven at 1.8V) static const uint32_t X300_USRP_PCIE_SSID_ADC_18 = 0x7861; static const uint32_t X310_USRP_PCIE_SSID_ADC_18 = 0x7862; static const uint32_t X310_2940R_40MHz_PCIE_SSID_ADC_18 = 0x7853; @@ -109,10 +109,10 @@ static const uint32_t X310_2954R_40MHz_PCIE_SSID_ADC_18 = 0x785A; static const uint32_t X310_2955R_PCIE_SSID_ADC_18 = 0x78F0; static const uint32_t X310_2974_PCIE_SSID_ADC_18 = 0x799B; -static const uint32_t FPGA_X3xx_SIG_VALUE = 0x58333030; +static const uint32_t FPGA_X3xx_SIG_VALUE = 0x58333030; -static const uint32_t PCIE_FPGA_ADDR_BASE = 0xC0000; -#define PCIE_FPGA_REG(X) (PCIE_FPGA_ADDR_BASE + (X)) +static const uint32_t PCIE_FPGA_ADDR_BASE = 0xC0000; +#define PCIE_FPGA_REG(X) (PCIE_FPGA_ADDR_BASE + (X)) static const uint32_t FPGA_PCIE_SIG_REG = PCIE_FPGA_REG(0x0000); static const uint32_t FPGA_CNTR_LO_REG = PCIE_FPGA_REG(0x0004); @@ -124,38 +124,40 @@ static const uint32_t FPGA_USR_SIG_REG_SIZE = 16; static const uint32_t FPGA_STATUS_DMA_ACTIVE_MASK = 0x3F3F0000; -static const uint32_t PCIE_TX_DMA_REG_BASE = PCIE_FPGA_REG(0x0200); -static const uint32_t PCIE_RX_DMA_REG_BASE = PCIE_FPGA_REG(0x0400); - -static const uint32_t DMA_REG_GRP_SIZE = 16; -static const uint32_t DMA_CTRL_STATUS_REG = 0x0; -static const uint32_t DMA_FRAME_SIZE_REG = 0x4; -static const uint32_t DMA_SAMPLE_COUNT_REG = 0x8; -static const uint32_t DMA_PKT_COUNT_REG = 0xC; - -#define PCIE_TX_DMA_REG(REG, CHAN) (PCIE_TX_DMA_REG_BASE + ((CHAN)*DMA_REG_GRP_SIZE) + (REG)) -#define PCIE_RX_DMA_REG(REG, CHAN) (PCIE_RX_DMA_REG_BASE + ((CHAN)*DMA_REG_GRP_SIZE) + (REG)) - -static const uint32_t DMA_CTRL_DISABLED = 0x00000000; -static const uint32_t DMA_CTRL_ENABLED = 0x00000002; -static const uint32_t DMA_CTRL_CLEAR_STB = 0x00000001; -static const uint32_t DMA_CTRL_SW_BUF_U64 = (3 << 4); -static const uint32_t DMA_CTRL_SW_BUF_U32 = (2 << 4); -static const uint32_t DMA_CTRL_SW_BUF_U16 = (1 << 4); -static const uint32_t DMA_CTRL_SW_BUF_U8 = (0 << 4); -static const uint32_t DMA_STATUS_ERROR = 0x00000001; -static const uint32_t DMA_STATUS_BUSY = 0x00000002; - -static const uint32_t PCIE_ROUTER_REG_BASE = PCIE_FPGA_REG(0x0500); -#define PCIE_ROUTER_REG(X) (PCIE_ROUTER_REG_BASE + (X)) - -static const uint32_t PCIE_ZPU_DATA_BASE = 0x30000; -static const uint32_t PCIE_ZPU_READ_BASE = 0x20000; //Trig and Status share the same base -static const uint32_t PCIE_ZPU_STATUS_BASE = 0x20000; - -#define PCIE_ZPU_DATA_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_DATA_BASE) + (X)) -#define PCIE_ZPU_READ_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_READ_BASE) + (X)) -#define PCIE_ZPU_STATUS_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_STATUS_BASE) + (X)) +static const uint32_t PCIE_TX_DMA_REG_BASE = PCIE_FPGA_REG(0x0200); +static const uint32_t PCIE_RX_DMA_REG_BASE = PCIE_FPGA_REG(0x0400); + +static const uint32_t DMA_REG_GRP_SIZE = 16; +static const uint32_t DMA_CTRL_STATUS_REG = 0x0; +static const uint32_t DMA_FRAME_SIZE_REG = 0x4; +static const uint32_t DMA_SAMPLE_COUNT_REG = 0x8; +static const uint32_t DMA_PKT_COUNT_REG = 0xC; + +#define PCIE_TX_DMA_REG(REG, CHAN) \ + (PCIE_TX_DMA_REG_BASE + ((CHAN)*DMA_REG_GRP_SIZE) + (REG)) +#define PCIE_RX_DMA_REG(REG, CHAN) \ + (PCIE_RX_DMA_REG_BASE + ((CHAN)*DMA_REG_GRP_SIZE) + (REG)) + +static const uint32_t DMA_CTRL_DISABLED = 0x00000000; +static const uint32_t DMA_CTRL_ENABLED = 0x00000002; +static const uint32_t DMA_CTRL_CLEAR_STB = 0x00000001; +static const uint32_t DMA_CTRL_SW_BUF_U64 = (3 << 4); +static const uint32_t DMA_CTRL_SW_BUF_U32 = (2 << 4); +static const uint32_t DMA_CTRL_SW_BUF_U16 = (1 << 4); +static const uint32_t DMA_CTRL_SW_BUF_U8 = (0 << 4); +static const uint32_t DMA_STATUS_ERROR = 0x00000001; +static const uint32_t DMA_STATUS_BUSY = 0x00000002; + +static const uint32_t PCIE_ROUTER_REG_BASE = PCIE_FPGA_REG(0x0500); +#define PCIE_ROUTER_REG(X) (PCIE_ROUTER_REG_BASE + (X)) + +static const uint32_t PCIE_ZPU_DATA_BASE = 0x30000; +static const uint32_t PCIE_ZPU_READ_BASE = 0x20000; // Trig and Status share the same base +static const uint32_t PCIE_ZPU_STATUS_BASE = 0x20000; + +#define PCIE_ZPU_DATA_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_DATA_BASE) + (X)) +#define PCIE_ZPU_READ_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_READ_BASE) + (X)) +#define PCIE_ZPU_STATUS_REG(X) (PCIE_FPGA_REG(PCIE_ZPU_STATUS_BASE) + (X)) static const uint32_t PCIE_ZPU_READ_START = 0x0; static const uint32_t PCIE_ZPU_READ_CLOBBER = 0x80000000; @@ -166,63 +168,72 @@ static const uint32_t PCIE_ZPU_STATUS_SUSPENDED = 0x80000000; // Register Maps //------------------------------------------------------------------- namespace uhd { namespace usrp { namespace x300 { - class fw_regmap_t : public uhd::soft_regmap_t { +class fw_regmap_t : public uhd::soft_regmap_t +{ +public: + typedef boost::shared_ptr<fw_regmap_t> sptr; + + class clk_ctrl_reg_t : public uhd::soft_reg32_wo_t + { public: - typedef boost::shared_ptr<fw_regmap_t> sptr; - - class clk_ctrl_reg_t : public uhd::soft_reg32_wo_t { - public: - UHD_DEFINE_SOFT_REG_FIELD(CLK_SOURCE, /*width*/ 2, /*shift*/ 0); //[1:0] - UHD_DEFINE_SOFT_REG_FIELD(PPS_SELECT, /*width*/ 2, /*shift*/ 2); //[3:2] - UHD_DEFINE_SOFT_REG_FIELD(PPS_OUT_EN, /*width*/ 1, /*shift*/ 4); //[4] - UHD_DEFINE_SOFT_REG_FIELD(TCXO_EN, /*width*/ 1, /*shift*/ 5); //[5] - UHD_DEFINE_SOFT_REG_FIELD(GPSDO_PWR_EN, /*width*/ 1, /*shift*/ 6); //[6] - UHD_DEFINE_SOFT_REG_FIELD(TIME_SYNC, /*width*/ 1, /*shift*/ 7); //[7] - - static const uint32_t SRC_EXTERNAL = 0x0; - static const uint32_t SRC_INTERNAL = 0x2; - static const uint32_t SRC_GPSDO = 0x3; - - clk_ctrl_reg_t(): uhd::soft_reg32_wo_t(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL)) { - //Initial values - set(CLK_SOURCE, SRC_INTERNAL); - set(PPS_SELECT, SRC_INTERNAL); - set(PPS_OUT_EN, 0); - set(TCXO_EN, 1); - set(GPSDO_PWR_EN, 1); //GPSDO power always ON - set(TIME_SYNC, 0); - } - } clock_ctrl_reg; - - class clk_status_reg_t : public uhd::soft_reg32_ro_t { - public: - UHD_DEFINE_SOFT_REG_FIELD(LMK_STATUS, /*width*/ 2, /*shift*/ 0); //[1:0] - UHD_DEFINE_SOFT_REG_FIELD(LMK_LOCK, /*width*/ 1, /*shift*/ 2); //[2] - UHD_DEFINE_SOFT_REG_FIELD(LMK_HOLDOVER, /*width*/ 1, /*shift*/ 3); //[3] - UHD_DEFINE_SOFT_REG_FIELD(PPS_DETECT, /*width*/ 1, /*shift*/ 4); //[4] - UHD_DEFINE_SOFT_REG_FIELD(RADIO_CLK_LOCK, /*width*/ 1, /*shift*/ 5); //[5] - UHD_DEFINE_SOFT_REG_FIELD(IDELAYCTRL_LOCK, /*width*/ 1, /*shift*/ 6); //[6] - - clk_status_reg_t(): uhd::soft_reg32_ro_t(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) {} - } clock_status_reg; - - class ref_freq_reg_t : public uhd::soft_reg32_wo_t { - public: - UHD_DEFINE_SOFT_REG_FIELD(REF_FREQ, /*width*/ 32, /*shift*/ 0); - - ref_freq_reg_t(): uhd::soft_reg32_wo_t(SR_ADDR(SET0_BASE, ZPU_SR_REF_FREQ)) { - //Initial values - set(REF_FREQ, 10000000); - } - } ref_freq_reg; - - fw_regmap_t() : soft_regmap_t("fw_regmap") { - add_to_map(clock_ctrl_reg, "clock_ctrl_reg", PUBLIC); - add_to_map(clock_status_reg, "clock_status_reg", PUBLIC); - add_to_map(ref_freq_reg, "ref_freq_reg", PUBLIC); + UHD_DEFINE_SOFT_REG_FIELD(CLK_SOURCE, /*width*/ 2, /*shift*/ 0); //[1:0] + UHD_DEFINE_SOFT_REG_FIELD(PPS_SELECT, /*width*/ 2, /*shift*/ 2); //[3:2] + UHD_DEFINE_SOFT_REG_FIELD(PPS_OUT_EN, /*width*/ 1, /*shift*/ 4); //[4] + UHD_DEFINE_SOFT_REG_FIELD(TCXO_EN, /*width*/ 1, /*shift*/ 5); //[5] + UHD_DEFINE_SOFT_REG_FIELD(GPSDO_PWR_EN, /*width*/ 1, /*shift*/ 6); //[6] + UHD_DEFINE_SOFT_REG_FIELD(TIME_SYNC, /*width*/ 1, /*shift*/ 7); //[7] + + static const uint32_t SRC_EXTERNAL = 0x0; + static const uint32_t SRC_INTERNAL = 0x2; + static const uint32_t SRC_GPSDO = 0x3; + + clk_ctrl_reg_t() : uhd::soft_reg32_wo_t(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL)) + { + // Initial values + set(CLK_SOURCE, SRC_INTERNAL); + set(PPS_SELECT, SRC_INTERNAL); + set(PPS_OUT_EN, 0); + set(TCXO_EN, 1); + set(GPSDO_PWR_EN, 1); // GPSDO power always ON + set(TIME_SYNC, 0); } - }; + } clock_ctrl_reg; + + class clk_status_reg_t : public uhd::soft_reg32_ro_t + { + public: + UHD_DEFINE_SOFT_REG_FIELD(LMK_STATUS, /*width*/ 2, /*shift*/ 0); //[1:0] + UHD_DEFINE_SOFT_REG_FIELD(LMK_LOCK, /*width*/ 1, /*shift*/ 2); //[2] + UHD_DEFINE_SOFT_REG_FIELD(LMK_HOLDOVER, /*width*/ 1, /*shift*/ 3); //[3] + UHD_DEFINE_SOFT_REG_FIELD(PPS_DETECT, /*width*/ 1, /*shift*/ 4); //[4] + UHD_DEFINE_SOFT_REG_FIELD(RADIO_CLK_LOCK, /*width*/ 1, /*shift*/ 5); //[5] + UHD_DEFINE_SOFT_REG_FIELD(IDELAYCTRL_LOCK, /*width*/ 1, /*shift*/ 6); //[6] + + clk_status_reg_t() : uhd::soft_reg32_ro_t(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) + { + } + } clock_status_reg; + + class ref_freq_reg_t : public uhd::soft_reg32_wo_t + { + public: + UHD_DEFINE_SOFT_REG_FIELD(REF_FREQ, /*width*/ 32, /*shift*/ 0); + + ref_freq_reg_t() : uhd::soft_reg32_wo_t(SR_ADDR(SET0_BASE, ZPU_SR_REF_FREQ)) + { + // Initial values + set(REF_FREQ, 10000000); + } + } ref_freq_reg; + + fw_regmap_t() : soft_regmap_t("fw_regmap") + { + add_to_map(clock_ctrl_reg, "clock_ctrl_reg", PUBLIC); + add_to_map(clock_status_reg, "clock_status_reg", PUBLIC); + add_to_map(ref_freq_reg, "ref_freq_reg", PUBLIC); + } +}; -}}} +}}} // namespace uhd::usrp::x300 #endif /* INCLUDED_X300_REGS_HPP */ diff --git a/host/tests/addr_test.cpp b/host/tests/addr_test.cpp index 9819df1a5..03608d723 100644 --- a/host/tests/addr_test.cpp +++ b/host/tests/addr_test.cpp @@ -5,15 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> -#include <uhd/types/mac_addr.hpp> #include <uhd/types/device_addr.hpp> +#include <uhd/types/mac_addr.hpp> #include <uhd/usrp/dboard_id.hpp> #include <boost/assign/list_of.hpp> +#include <boost/test/unit_test.hpp> #include <algorithm> #include <iostream> -BOOST_AUTO_TEST_CASE(test_mac_addr){ +BOOST_AUTO_TEST_CASE(test_mac_addr) +{ std::cout << "Testing mac addr..." << std::endl; const std::string mac_addr_str("00:01:23:45:67:89"); uhd::mac_addr_t mac_addr = uhd::mac_addr_t::from_string(mac_addr_str); @@ -22,39 +23,40 @@ BOOST_AUTO_TEST_CASE(test_mac_addr){ BOOST_CHECK_EQUAL(mac_addr_str, mac_addr.to_string()); } -BOOST_AUTO_TEST_CASE(test_device_addr){ +BOOST_AUTO_TEST_CASE(test_device_addr) +{ std::cout << "Testing device addr..." << std::endl; - //load the device address with something + // load the device address with something uhd::device_addr_t dev_addr; dev_addr["key1"] = "val1"; dev_addr["key1"] = "val1"; dev_addr["key3"] = ""; - //convert to and from args string + // convert to and from args string std::cout << "Pretty Print: " << std::endl << dev_addr.to_pp_string(); std::string args_str = dev_addr.to_string(); std::cout << "Args String: " << args_str << std::endl; uhd::device_addr_t new_dev_addr(args_str); - //they should be the same size + // they should be the same size BOOST_REQUIRE_EQUAL(dev_addr.size(), new_dev_addr.size()); - //the keys should match + // the keys should match std::vector<std::string> old_dev_addr_keys = dev_addr.keys(); std::vector<std::string> new_dev_addr_keys = new_dev_addr.keys(); - BOOST_CHECK_EQUAL_COLLECTIONS( - old_dev_addr_keys.begin(), old_dev_addr_keys.end(), - new_dev_addr_keys.begin(), new_dev_addr_keys.end() - ); + BOOST_CHECK_EQUAL_COLLECTIONS(old_dev_addr_keys.begin(), + old_dev_addr_keys.end(), + new_dev_addr_keys.begin(), + new_dev_addr_keys.end()); - //the vals should match + // the vals should match std::vector<std::string> old_dev_addr_vals = dev_addr.vals(); std::vector<std::string> new_dev_addr_vals = new_dev_addr.vals(); - BOOST_CHECK_EQUAL_COLLECTIONS( - old_dev_addr_vals.begin(), old_dev_addr_vals.end(), - new_dev_addr_vals.begin(), new_dev_addr_vals.end() - ); + BOOST_CHECK_EQUAL_COLLECTIONS(old_dev_addr_vals.begin(), + old_dev_addr_vals.end(), + new_dev_addr_vals.begin(), + new_dev_addr_vals.end()); uhd::device_addr_t dev_addr_lhs1("key1=val1,key2=val2"); dev_addr_lhs1.update(uhd::device_addr_t("key2=val2x,key3=val3"), false); @@ -64,7 +66,8 @@ BOOST_AUTO_TEST_CASE(test_device_addr){ std::cout << "Merged: " << dev_addr_lhs1.to_string() << std::endl; } -BOOST_AUTO_TEST_CASE(test_dboard_id){ +BOOST_AUTO_TEST_CASE(test_dboard_id) +{ std::cout << "Testing dboard id..." << std::endl; using namespace uhd::usrp; @@ -76,7 +79,8 @@ BOOST_AUTO_TEST_CASE(test_dboard_id){ std::cout << "Pretty Print: " << std::endl << dboard_id_t::none().to_pp_string(); } -BOOST_AUTO_TEST_CASE(test_map_device_addr){ +BOOST_AUTO_TEST_CASE(test_map_device_addr) +{ std::map<std::string, std::string> dev_addr_map; dev_addr_map["key1"] = "val1"; dev_addr_map["key2"] = "val2"; diff --git a/host/tests/block_id_test.cpp b/host/tests/block_id_test.cpp index 51be3a2a2..7c068e4d2 100644 --- a/host/tests/block_id_test.cpp +++ b/host/tests/block_id_test.cpp @@ -5,14 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <iostream> -#include <boost/test/unit_test.hpp> #include <uhd/exception.hpp> #include <uhd/rfnoc/block_id.hpp> +#include <boost/test/unit_test.hpp> +#include <iostream> using namespace uhd::rfnoc; -BOOST_AUTO_TEST_CASE(test_block_id) { +BOOST_AUTO_TEST_CASE(test_block_id) +{ BOOST_CHECK(block_id_t::is_valid_block_id("00/Filter_1")); BOOST_CHECK(not block_id_t::is_valid_block_id("0/MAG_SQUARE")); BOOST_CHECK(block_id_t::is_valid_blockname("FilterFoo")); @@ -45,7 +46,8 @@ BOOST_AUTO_TEST_CASE(test_block_id) { BOOST_CHECK(not block_id.set_block_name("Foo_Bar")); BOOST_CHECK_EQUAL(block_id.get_device_no(), 17); - BOOST_CHECK_EQUAL(block_id.get_block_name(), "FooBar"); // Is unchanged because invalid + BOOST_CHECK_EQUAL( + block_id.get_block_name(), "FooBar"); // Is unchanged because invalid BOOST_CHECK_EQUAL(block_id.get_block_count(), 11); block_id++; @@ -82,7 +84,8 @@ BOOST_AUTO_TEST_CASE(test_block_id) { BOOST_CHECK(not other_block_id.match("2093ksdjfflsdkjf")); } -BOOST_AUTO_TEST_CASE(test_block_id_set) { +BOOST_AUTO_TEST_CASE(test_block_id_set) +{ // test set() block_id_t block_id_for_set(5, "Blockname", 9); block_id_for_set.set("FirFilter"); @@ -99,9 +102,10 @@ BOOST_AUTO_TEST_CASE(test_block_id_set) { BOOST_CHECK_EQUAL(block_id_for_set.get_block_count(), 3); } -BOOST_AUTO_TEST_CASE(test_block_id_cmp) { +BOOST_AUTO_TEST_CASE(test_block_id_cmp) +{ BOOST_CHECK(block_id_t("0/FFT_1") == block_id_t("0/FFT_1")); BOOST_CHECK(block_id_t("0/FFT_1") != block_id_t("1/FFT_1")); BOOST_CHECK(block_id_t("0/FFT_1") < block_id_t("1/aaaaaaaaa_0")); - BOOST_CHECK(not (block_id_t("0/FFT_1") > block_id_t("1/aaaaaaaaa_0"))); + BOOST_CHECK(not(block_id_t("0/FFT_1") > block_id_t("1/aaaaaaaaa_0"))); } diff --git a/host/tests/blockdef_test.cpp b/host/tests/blockdef_test.cpp index bc513bebd..7a663f514 100644 --- a/host/tests/blockdef_test.cpp +++ b/host/tests/blockdef_test.cpp @@ -5,30 +5,28 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <iostream> -#include <map> +#include <uhd/rfnoc/blockdef.hpp> #include <stdint.h> -#include <boost/test/unit_test.hpp> #include <boost/format.hpp> -#include <uhd/rfnoc/blockdef.hpp> +#include <boost/test/unit_test.hpp> +#include <iostream> +#include <map> using namespace uhd::rfnoc; -BOOST_AUTO_TEST_CASE(test_lookup) { - const std::map<uint64_t, std::string> blocknames{ - {0, "NullSrcSink"}, +BOOST_AUTO_TEST_CASE(test_lookup) +{ + const std::map<uint64_t, std::string> blocknames{{0, "NullSrcSink"}, {0xFF70000000000000, "FFT"}, {0xF112000000000001, "FIR"}, {0xF1F0000000000000, "FIFO"}, {0xD053000000000000, "Window"}, - {0x5CC0000000000000, "SchmidlCox"} - }; + {0x5CC0000000000000, "SchmidlCox"}}; std::cout << blocknames.size() << std::endl; for (const auto block : blocknames) { - std::cout << "Testing " << block.second - << " => " << str(boost::format("%016X") % block.first) - << std::endl; + std::cout << "Testing " << block.second << " => " + << str(boost::format("%016X") % block.first) << std::endl; auto block_definition = blockdef::make_from_noc_id(block.first); // If the previous function fails, it'll return a NULL pointer BOOST_REQUIRE(block_definition); @@ -37,10 +35,11 @@ BOOST_AUTO_TEST_CASE(test_lookup) { } } -BOOST_AUTO_TEST_CASE(test_ports) { +BOOST_AUTO_TEST_CASE(test_ports) +{ // Create an FFT: blockdef::sptr block_definition = blockdef::make_from_noc_id(0xFF70000000000000); - blockdef::ports_t in_ports = block_definition->get_input_ports(); + blockdef::ports_t in_ports = block_definition->get_input_ports(); BOOST_REQUIRE_EQUAL(in_ports.size(), 1); BOOST_CHECK_EQUAL(in_ports[0]["name"], "in"); BOOST_CHECK_EQUAL(in_ports[0]["type"], "sc16"); @@ -57,20 +56,22 @@ BOOST_AUTO_TEST_CASE(test_ports) { BOOST_CHECK_EQUAL(block_definition->get_all_port_numbers()[0], 0); } -BOOST_AUTO_TEST_CASE(test_args) { +BOOST_AUTO_TEST_CASE(test_args) +{ // Create an FFT: blockdef::sptr block_definition = blockdef::make_from_noc_id(0xFF70000000000000); - blockdef::args_t args = block_definition->get_args(); + blockdef::args_t args = block_definition->get_args(); BOOST_REQUIRE_EQUAL(args.size(), 7); BOOST_CHECK_EQUAL(args[0]["name"], "spp"); BOOST_CHECK_EQUAL(args[0]["type"], "int"); BOOST_CHECK_EQUAL(args[0]["value"], "256"); } -BOOST_AUTO_TEST_CASE(test_regs) { +BOOST_AUTO_TEST_CASE(test_regs) +{ // Create an FFT: blockdef::sptr block_definition = blockdef::make_from_noc_id(0xFF70000000000000); - blockdef::registers_t sregs = block_definition->get_settings_registers(); + blockdef::registers_t sregs = block_definition->get_settings_registers(); BOOST_REQUIRE_EQUAL(sregs.size(), 6); BOOST_CHECK_EQUAL(sregs["FFT_RESET"], 131); BOOST_CHECK_EQUAL(sregs["FFT_SIZE_LOG2"], 132); @@ -80,4 +81,3 @@ BOOST_AUTO_TEST_CASE(test_regs) { BOOST_CHECK_EQUAL(user_regs["RB_FFT_RESET"], 0); BOOST_CHECK_EQUAL(user_regs["RB_MAGNITUDE_OUT"], 1); } - diff --git a/host/tests/buffer_test.cpp b/host/tests/buffer_test.cpp index b2659a86b..ef4c68ff2 100644 --- a/host/tests/buffer_test.cpp +++ b/host/tests/buffer_test.cpp @@ -5,26 +5,27 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/transport/bounded_buffer.hpp> #include <boost/assign/list_of.hpp> +#include <boost/test/unit_test.hpp> using namespace boost::assign; using namespace uhd::transport; -static const double timeout = 0.01/*secs*/; +static const double timeout = 0.01 /*secs*/; -BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_timed_wait){ +BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_timed_wait) +{ bounded_buffer<int> bb(3); - //push elements, check for timeout + // push elements, check for timeout BOOST_CHECK(bb.push_with_timed_wait(0, timeout)); BOOST_CHECK(bb.push_with_timed_wait(1, timeout)); BOOST_CHECK(bb.push_with_timed_wait(2, timeout)); BOOST_CHECK(not bb.push_with_timed_wait(3, timeout)); int val; - //pop elements, check for timeout and check values + // pop elements, check for timeout and check values BOOST_CHECK(bb.pop_with_timed_wait(val, timeout)); BOOST_CHECK_EQUAL(val, 0); BOOST_CHECK(bb.pop_with_timed_wait(val, timeout)); @@ -34,17 +35,18 @@ BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_timed_wait){ BOOST_CHECK(not bb.pop_with_timed_wait(val, timeout)); } -BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_pop_on_full){ +BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_pop_on_full) +{ bounded_buffer<int> bb(3); - //push elements, check for timeout + // push elements, check for timeout BOOST_CHECK(bb.push_with_pop_on_full(0)); BOOST_CHECK(bb.push_with_pop_on_full(1)); BOOST_CHECK(bb.push_with_pop_on_full(2)); BOOST_CHECK(not bb.push_with_pop_on_full(3)); int val; - //pop elements, check for timeout and check values + // pop elements, check for timeout and check values BOOST_CHECK(bb.pop_with_timed_wait(val, timeout)); BOOST_CHECK_EQUAL(val, 1); BOOST_CHECK(bb.pop_with_timed_wait(val, timeout)); diff --git a/host/tests/byteswap_test.cpp b/host/tests/byteswap_test.cpp index c006de169..4cc04f484 100644 --- a/host/tests/byteswap_test.cpp +++ b/host/tests/byteswap_test.cpp @@ -5,25 +5,27 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/utils/byteswap.hpp> +#include <boost/test/unit_test.hpp> -BOOST_AUTO_TEST_CASE(test_byteswap16){ +BOOST_AUTO_TEST_CASE(test_byteswap16) +{ uint16_t x = 0x0123; uint16_t y = 0x2301; BOOST_CHECK_EQUAL(uhd::byteswap(x), y); } -BOOST_AUTO_TEST_CASE(test_byteswap32){ +BOOST_AUTO_TEST_CASE(test_byteswap32) +{ uint32_t x = 0x01234567; uint32_t y = 0x67452301; BOOST_CHECK_EQUAL(uhd::byteswap(x), y); } -BOOST_AUTO_TEST_CASE(test_byteswap64){ - //split up 64 bit constants to avoid long-long compiler warnings +BOOST_AUTO_TEST_CASE(test_byteswap64) +{ + // split up 64 bit constants to avoid long-long compiler warnings uint64_t x = 0x01234567 | (uint64_t(0x89abcdef) << 32); uint64_t y = 0xefcdab89 | (uint64_t(0x67452301) << 32); BOOST_CHECK_EQUAL(uhd::byteswap(x), y); } - diff --git a/host/tests/cal_container_test.cpp b/host/tests/cal_container_test.cpp index 559a674c1..4957b0b0d 100644 --- a/host/tests/cal_container_test.cpp +++ b/host/tests/cal_container_test.cpp @@ -7,10 +7,10 @@ #include <uhd/cal/power_container.hpp> #include <uhd/exception.hpp> -#include <boost/test/unit_test.hpp> #include <boost/shared_ptr.hpp> -#include <vector> +#include <boost/test/unit_test.hpp> #include <fstream> +#include <vector> using namespace uhd; using namespace uhd::cal; @@ -18,8 +18,9 @@ using namespace uhd::cal; static const double eps = 1e-8; //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_power_container_bilinear){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_power_container_bilinear) +{ + //////////////////////////////////////////////////////////////////////// // Create the data container power_container::sptr container = power_container::make(); @@ -51,8 +52,9 @@ BOOST_AUTO_TEST_CASE(test_power_container_bilinear){ //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_power_temp_container){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_power_temp_container) +{ + //////////////////////////////////////////////////////////////////////// // Create the data container power_container::sptr container = power_container::make(); @@ -80,8 +82,9 @@ BOOST_AUTO_TEST_CASE(test_power_temp_container){ } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_power_container_metadata){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_power_container_metadata) +{ + //////////////////////////////////////////////////////////////////////// // Create the data container power_container::sptr container = power_container::make(); @@ -90,7 +93,7 @@ BOOST_AUTO_TEST_CASE(test_power_container_metadata){ base_container::metadata_t data; std::string fake_serial = "F2A432"; - data["x300"] = fake_serial; + data["x300"] = fake_serial; // Add some metadata container->add_metadata(data); @@ -102,8 +105,9 @@ BOOST_AUTO_TEST_CASE(test_power_container_metadata){ } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_power_serialization){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_power_serialization) +{ + //////////////////////////////////////////////////////////////////////// // Create the data container power_container::sptr container = power_container::make(); @@ -112,7 +116,7 @@ BOOST_AUTO_TEST_CASE(test_power_serialization){ base_container::metadata_t data; std::string fake_serial = "F2A432"; - data["x300"] = fake_serial; + data["x300"] = fake_serial; // Add some metadata container->add_metadata(data); @@ -167,8 +171,9 @@ BOOST_AUTO_TEST_CASE(test_power_serialization){ } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_interp_singular){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_interp_singular) +{ + //////////////////////////////////////////////////////////////////////// // Create the data container power_container::sptr container = power_container::make(); diff --git a/host/tests/cast_test.cpp b/host/tests/cast_test.cpp index d1357459e..296574b48 100644 --- a/host/tests/cast_test.cpp +++ b/host/tests/cast_test.cpp @@ -5,19 +5,18 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <iostream> -#include <boost/test/unit_test.hpp> -#include <stdint.h> #include <uhd/utils/cast.hpp> +#include <stdint.h> +#include <boost/test/unit_test.hpp> +#include <iostream> -BOOST_AUTO_TEST_CASE(test_mac_addr){ - std::string in = "0x0100"; +BOOST_AUTO_TEST_CASE(test_mac_addr) +{ + std::string in = "0x0100"; uint16_t correct_result = 256; - uint16_t x = uhd::cast::hexstr_cast<uint16_t>(in); - //uint16_t x = uhd::cast::hexstr_cast(in); - std::cout - << "Testing hex -> uint16_t conversion. " - << in << " == " << std::hex << x << "?" << std::endl; + uint16_t x = uhd::cast::hexstr_cast<uint16_t>(in); + // uint16_t x = uhd::cast::hexstr_cast(in); + std::cout << "Testing hex -> uint16_t conversion. " << in << " == " << std::hex << x + << "?" << std::endl; BOOST_CHECK_EQUAL(x, correct_result); } - diff --git a/host/tests/chdr_test.cpp b/host/tests/chdr_test.cpp index 11daca521..595d7011a 100644 --- a/host/tests/chdr_test.cpp +++ b/host/tests/chdr_test.cpp @@ -7,128 +7,131 @@ #include <uhd/transport/chdr.hpp> #include <uhd/utils/byteswap.hpp> -#include <boost/test/unit_test.hpp> #include <boost/format.hpp> +#include <boost/test/unit_test.hpp> #include <cstdlib> #include <iostream> using namespace uhd::transport::vrt; -static void pack_and_unpack( - if_packet_info_t &if_packet_info_in -){ +static void pack_and_unpack(if_packet_info_t& if_packet_info_in) +{ // Temp buffer for packed packet uint32_t packet_buff[2048] = {0}; // Check input (must not be lazy) - BOOST_REQUIRE( - (if_packet_info_in.num_payload_words32 == 0 and if_packet_info_in.num_payload_bytes == 0) - or - (if_packet_info_in.num_payload_words32 != 0 and if_packet_info_in.num_payload_bytes != 0) - ); + BOOST_REQUIRE((if_packet_info_in.num_payload_words32 == 0 + and if_packet_info_in.num_payload_bytes == 0) + or (if_packet_info_in.num_payload_words32 != 0 + and if_packet_info_in.num_payload_bytes != 0)); if (if_packet_info_in.num_payload_words32) { - BOOST_REQUIRE(if_packet_info_in.num_payload_bytes <= 4 * if_packet_info_in.num_payload_words32); - BOOST_REQUIRE(if_packet_info_in.num_payload_bytes > 4*(if_packet_info_in.num_payload_words32-1)); + BOOST_REQUIRE(if_packet_info_in.num_payload_bytes + <= 4 * if_packet_info_in.num_payload_words32); + BOOST_REQUIRE(if_packet_info_in.num_payload_bytes + > 4 * (if_packet_info_in.num_payload_words32 - 1)); } - //pack metadata into a vrt header - chdr::if_hdr_pack_be( - packet_buff, if_packet_info_in - ); + // pack metadata into a vrt header + chdr::if_hdr_pack_be(packet_buff, if_packet_info_in); std::cout << std::endl; uint32_t header_bits = (uhd::ntohx(packet_buff[0]) >> 28); std::cout << boost::format("header bits = 0b%d%d%d%d") % ((header_bits & 8) > 0) - % ((header_bits & 4) > 0) - % ((header_bits & 2) > 0) - % ((header_bits & 1) > 0) << std::endl; - for (size_t i = 0; i < 5; i++) - { - std::cout << boost::format("packet_buff[%u] = 0x%08x") % i % uhd::ntohx(packet_buff[i]) << std::endl; + % ((header_bits & 4) > 0) % ((header_bits & 2) > 0) + % ((header_bits & 1) > 0) + << std::endl; + for (size_t i = 0; i < 5; i++) { + std::cout << boost::format("packet_buff[%u] = 0x%08x") % i + % uhd::ntohx(packet_buff[i]) + << std::endl; } if_packet_info_t if_packet_info_out; // Must be set a-priori as per contract if_packet_info_out.num_packet_words32 = if_packet_info_in.num_packet_words32; - //unpack the vrt header back into metadata - chdr::if_hdr_unpack_be( - packet_buff, if_packet_info_out - ); + // unpack the vrt header back into metadata + chdr::if_hdr_unpack_be(packet_buff, if_packet_info_out); - //check the the unpacked metadata is the same + // check the the unpacked metadata is the same BOOST_CHECK_EQUAL(if_packet_info_in.packet_count, if_packet_info_out.packet_count); - BOOST_CHECK_EQUAL(if_packet_info_in.num_header_words32, if_packet_info_out.num_header_words32); - BOOST_CHECK_EQUAL(if_packet_info_in.num_payload_words32, if_packet_info_out.num_payload_words32); + BOOST_CHECK_EQUAL( + if_packet_info_in.num_header_words32, if_packet_info_out.num_header_words32); + BOOST_CHECK_EQUAL( + if_packet_info_in.num_payload_words32, if_packet_info_out.num_payload_words32); BOOST_CHECK(if_packet_info_out.has_sid); BOOST_CHECK_EQUAL(if_packet_info_in.sid, if_packet_info_out.sid); BOOST_CHECK(if_packet_info_out.has_sid); BOOST_CHECK_EQUAL(if_packet_info_in.has_tsf, if_packet_info_out.has_tsf); - if (if_packet_info_in.has_tsf and if_packet_info_out.has_tsf){ + if (if_packet_info_in.has_tsf and if_packet_info_out.has_tsf) { BOOST_CHECK_EQUAL(if_packet_info_in.tsf, if_packet_info_out.tsf); } } -BOOST_AUTO_TEST_CASE(test_with_chdr){ +BOOST_AUTO_TEST_CASE(test_with_chdr) +{ if_packet_info_t if_packet_info; - if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_DATA; - if_packet_info.eob = false; - if_packet_info.packet_count = 7; - if_packet_info.has_tsf = true; - if_packet_info.tsf = 0x1234567890ABCDEFull; - if_packet_info.sid = 0xAABBCCDD; + if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_DATA; + if_packet_info.eob = false; + if_packet_info.packet_count = 7; + if_packet_info.has_tsf = true; + if_packet_info.tsf = 0x1234567890ABCDEFull; + if_packet_info.sid = 0xAABBCCDD; if_packet_info.num_payload_words32 = 24; - if_packet_info.num_payload_bytes = 95; + if_packet_info.num_payload_bytes = 95; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_chdr_fc){ +BOOST_AUTO_TEST_CASE(test_with_chdr_fc) +{ if_packet_info_t if_packet_info; - if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_FC; - if_packet_info.eob = false; - if_packet_info.packet_count = 19; - if_packet_info.has_tsf = false; - if_packet_info.tsf = 0x1234567890ABCDEFull; - if_packet_info.sid = 0xAABBCCDD; + if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_FC; + if_packet_info.eob = false; + if_packet_info.packet_count = 19; + if_packet_info.has_tsf = false; + if_packet_info.tsf = 0x1234567890ABCDEFull; + if_packet_info.sid = 0xAABBCCDD; if_packet_info.num_payload_words32 = 4; - if_packet_info.num_payload_bytes = 16; + if_packet_info.num_payload_bytes = 16; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_chdr_cmd){ +BOOST_AUTO_TEST_CASE(test_with_chdr_cmd) +{ if_packet_info_t if_packet_info; - if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_CMD; - if_packet_info.packet_count = 19; - if_packet_info.has_tsf = true; - if_packet_info.tsf = 0x1234567890ABCDEFull; - if_packet_info.sid = 0xAABBCCDD; + if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_CMD; + if_packet_info.packet_count = 19; + if_packet_info.has_tsf = true; + if_packet_info.tsf = 0x1234567890ABCDEFull; + if_packet_info.sid = 0xAABBCCDD; if_packet_info.num_payload_words32 = 4; - if_packet_info.num_payload_bytes = 16; + if_packet_info.num_payload_bytes = 16; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_chdr_resp){ +BOOST_AUTO_TEST_CASE(test_with_chdr_resp) +{ if_packet_info_t if_packet_info; - if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_RESP; - if_packet_info.packet_count = 123; - if_packet_info.has_tsf = false; - if_packet_info.tsf = 0x1234567890ABCDEFull; - if_packet_info.sid = 0xAABBCCDD; + if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_RESP; + if_packet_info.packet_count = 123; + if_packet_info.has_tsf = false; + if_packet_info.tsf = 0x1234567890ABCDEFull; + if_packet_info.sid = 0xAABBCCDD; if_packet_info.num_payload_words32 = 4; - if_packet_info.num_payload_bytes = 16; + if_packet_info.num_payload_bytes = 16; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_chdr_err){ +BOOST_AUTO_TEST_CASE(test_with_chdr_err) +{ if_packet_info_t if_packet_info; - if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_ERROR; - if_packet_info.packet_count = 1928; - if_packet_info.eob = false; - if_packet_info.error = false; // Needs to be set explicitly - if_packet_info.has_tsf = false; - if_packet_info.tsf = 0x1234567890ABCDEFull; - if_packet_info.sid = 0xAABBCCDD; + if_packet_info.packet_type = if_packet_info_t::PACKET_TYPE_ERROR; + if_packet_info.packet_count = 1928; + if_packet_info.eob = false; + if_packet_info.error = false; // Needs to be set explicitly + if_packet_info.has_tsf = false; + if_packet_info.tsf = 0x1234567890ABCDEFull; + if_packet_info.sid = 0xAABBCCDD; if_packet_info.num_payload_words32 = 4; - if_packet_info.num_payload_bytes = 16; + if_packet_info.num_payload_bytes = 16; pack_and_unpack(if_packet_info); } - diff --git a/host/tests/common/mock_ctrl_iface_impl.cpp b/host/tests/common/mock_ctrl_iface_impl.cpp index 0e80ef9a0..e8560ad9e 100644 --- a/host/tests/common/mock_ctrl_iface_impl.cpp +++ b/host/tests/common/mock_ctrl_iface_impl.cpp @@ -7,16 +7,19 @@ #include "mock_ctrl_iface_impl.hpp" static const uint64_t TEST_NOC_ID = 0xAAAABBBBCCCCDDDD; -uint64_t mock_ctrl_iface_impl::send_cmd_pkt( - const size_t addr, - const size_t data, - const bool readback, - const uint64_t /* timestamp */ -) { +uint64_t mock_ctrl_iface_impl::send_cmd_pkt(const size_t addr, + const size_t data, + const bool readback, + const uint64_t /* timestamp */ +) +{ if (not readback) { - std::cout << str(boost::format("[MOCK] poke to addr: %016X, data == %016X") % addr % data) << std::endl; + std::cout << str(boost::format("[MOCK] poke to addr: %016X, data == %016X") % addr + % data) + << std::endl; } else { - std::cout << str(boost::format("[MOCK] peek64 to addr: %016X") % data) << std::endl; + std::cout << str(boost::format("[MOCK] peek64 to addr: %016X") % data) + << std::endl; switch (data) { case uhd::rfnoc::SR_READBACK_REG_ID: return TEST_NOC_ID; @@ -25,8 +28,8 @@ uint64_t mock_ctrl_iface_impl::send_cmd_pkt( case uhd::rfnoc::SR_READBACK_REG_USER: return 0x0123456789ABCDEF; case uhd::rfnoc::SR_READBACK_COMPAT: - return uhd::rfnoc::NOC_SHELL_COMPAT_MAJOR << 32 | - uhd::rfnoc::NOC_SHELL_COMPAT_MINOR; + return uhd::rfnoc::NOC_SHELL_COMPAT_MAJOR << 32 + | uhd::rfnoc::NOC_SHELL_COMPAT_MINOR; default: return 0; } diff --git a/host/tests/common/mock_ctrl_iface_impl.hpp b/host/tests/common/mock_ctrl_iface_impl.hpp index 8d2aafed6..ad60d32ef 100644 --- a/host/tests/common/mock_ctrl_iface_impl.hpp +++ b/host/tests/common/mock_ctrl_iface_impl.hpp @@ -10,21 +10,18 @@ #include <uhd/rfnoc/constants.hpp> #include <uhdlib/rfnoc/ctrl_iface.hpp> -#include <boost/thread/mutex.hpp> -#include <boost/thread/thread.hpp> -#include <boost/format.hpp> #include <boost/bind.hpp> +#include <boost/format.hpp> #include <boost/make_shared.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> #include <queue> class mock_ctrl_iface_impl : public uhd::rfnoc::ctrl_iface { - - uint64_t send_cmd_pkt( - const size_t addr, - const size_t data, - const bool readback=false, - const uint64_t timestamp=0 - ); + uint64_t send_cmd_pkt(const size_t addr, + const size_t data, + const bool readback = false, + const uint64_t timestamp = 0); }; #endif /* INCLUDED_MOCK_CTRL_IFACE_IMPL_HPP */
\ No newline at end of file diff --git a/host/tests/common/mock_zero_copy.cpp b/host/tests/common/mock_zero_copy.cpp index bc49c3f10..0843a0274 100644 --- a/host/tests/common/mock_zero_copy.cpp +++ b/host/tests/common/mock_zero_copy.cpp @@ -10,18 +10,19 @@ using namespace uhd::transport; -mock_zero_copy::mock_zero_copy( - vrt::if_packet_info_t::link_type_t link_type, +mock_zero_copy::mock_zero_copy(vrt::if_packet_info_t::link_type_t link_type, size_t recv_frame_size, - size_t send_frame_size -) : _link_type(link_type) - , _recv_frame_size(recv_frame_size) - , _send_frame_size(send_frame_size) { + size_t send_frame_size) + : _link_type(link_type) + , _recv_frame_size(recv_frame_size) + , _send_frame_size(send_frame_size) +{ } -uhd::transport::managed_recv_buffer::sptr mock_zero_copy::get_recv_buff(double) { +uhd::transport::managed_recv_buffer::sptr mock_zero_copy::get_recv_buff(double) +{ if (_simulate_io_error) { - throw uhd::io_error("IO error exception"); //simulate an IO error + throw uhd::io_error("IO error exception"); // simulate an IO error } if (_rx_mems.empty()) { return uhd::transport::managed_recv_buffer::sptr(); // timeout @@ -38,20 +39,22 @@ uhd::transport::managed_recv_buffer::sptr mock_zero_copy::get_recv_buff(double) return mrb; } -uhd::transport::managed_send_buffer::sptr mock_zero_copy::get_send_buff(double) { +uhd::transport::managed_send_buffer::sptr mock_zero_copy::get_send_buff(double) +{ if (not _reuse_send_memory or _tx_mems.size() == 0) { - _tx_mems.push_back( - boost::shared_array<uint8_t>(new uint8_t[_send_frame_size])); + _tx_mems.push_back(boost::shared_array<uint8_t>(new uint8_t[_send_frame_size])); _tx_lens.push_back(_send_frame_size); } return _msb.get_new(_tx_mems.back(), &_tx_lens.back()); } -void mock_zero_copy::set_reuse_recv_memory(bool reuse_recv) { +void mock_zero_copy::set_reuse_recv_memory(bool reuse_recv) +{ _reuse_recv_memory = reuse_recv; } -void mock_zero_copy::set_reuse_send_memory(bool reuse_send) { +void mock_zero_copy::set_reuse_send_memory(bool reuse_send) +{ _reuse_send_memory = reuse_send; } diff --git a/host/tests/common/mock_zero_copy.hpp b/host/tests/common/mock_zero_copy.hpp index 8d27c9b46..60e5f4659 100644 --- a/host/tests/common/mock_zero_copy.hpp +++ b/host/tests/common/mock_zero_copy.hpp @@ -7,18 +7,17 @@ #ifndef INCLUDED_MOCK_XPORT_HPP #define INCLUDED_MOCK_XPORT_HPP -#include <uhdlib/rfnoc/xports.hpp> +#include <uhd/exception.hpp> #include <uhd/transport/chdr.hpp> #include <uhd/transport/vrt_if_packet.hpp> #include <uhd/transport/zero_copy.hpp> #include <uhd/types/endianness.hpp> #include <uhd/types/sid.hpp> -#include <uhd/exception.hpp> #include <uhd/utils/byteswap.hpp> -#include <uhd/exception.hpp> +#include <uhdlib/rfnoc/xports.hpp> #include <boost/make_shared.hpp> -#include <boost/shared_ptr.hpp> #include <boost/shared_array.hpp> +#include <boost/shared_ptr.hpp> #include <list> #include <vector> @@ -36,89 +35,101 @@ static constexpr size_t DEFAULT_RECV_FRAME_SIZE = 1024; /*********************************************************************** * Dummy managed buffers for testing **********************************************************************/ -class mock_msb : public uhd::transport::managed_send_buffer { - public: - void release(void) { /* nop */ +class mock_msb : public uhd::transport::managed_send_buffer +{ +public: + void release(void) + { /* nop */ } - sptr get_new(boost::shared_array<uint8_t> mem, size_t* len) { + sptr get_new(boost::shared_array<uint8_t> mem, size_t* len) + { _mem = mem; return make(this, mem.get(), *len); } - private: +private: boost::shared_array<uint8_t> _mem; }; -class mock_mrb : public uhd::transport::managed_recv_buffer { - public: - void release(void) { /* nop */ +class mock_mrb : public uhd::transport::managed_recv_buffer +{ +public: + void release(void) + { /* nop */ } - sptr get_new(boost::shared_array<uint8_t> mem, size_t len) { + sptr get_new(boost::shared_array<uint8_t> mem, size_t len) + { _mem = mem; return make(this, _mem.get(), len); } - private: +private: boost::shared_array<uint8_t> _mem; }; -class mock_zero_copy : public uhd::transport::zero_copy_if { - public: +class mock_zero_copy : public uhd::transport::zero_copy_if +{ +public: typedef boost::shared_ptr<mock_zero_copy> sptr; - mock_zero_copy( - uhd::transport::vrt::if_packet_info_t::link_type_t type, + mock_zero_copy(uhd::transport::vrt::if_packet_info_t::link_type_t type, size_t recv_frame_size = DEFAULT_RECV_FRAME_SIZE, - size_t send_frame_size = DEFAULT_SEND_FRAME_SIZE - ); + size_t send_frame_size = DEFAULT_SEND_FRAME_SIZE); uhd::transport::managed_recv_buffer::sptr get_recv_buff(double); uhd::transport::managed_send_buffer::sptr get_send_buff(double); - size_t get_num_recv_frames(void) const { return 1; } - size_t get_num_send_frames(void) const { return 1; } - size_t get_recv_frame_size(void) const { return _recv_frame_size; } - size_t get_send_frame_size(void) const { return _send_frame_size; } + size_t get_num_recv_frames(void) const + { + return 1; + } + size_t get_num_send_frames(void) const + { + return 1; + } + size_t get_recv_frame_size(void) const + { + return _recv_frame_size; + } + size_t get_send_frame_size(void) const + { + return _send_frame_size; + } template <typename T> - void push_back_packet( - uhd::transport::vrt::if_packet_info_t& ifpi, + void push_back_packet(uhd::transport::vrt::if_packet_info_t& ifpi, const std::vector<T>& otw_data = std::vector<T>(), - uhd::endianness_t endianness = uhd::ENDIANNESS_BIG); + uhd::endianness_t endianness = uhd::ENDIANNESS_BIG); void set_reuse_recv_memory(bool reuse_recv); void set_reuse_send_memory(bool reuse_send); - void set_simulate_io_error(bool status) { _simulate_io_error = status; } + void set_simulate_io_error(bool status) + { + _simulate_io_error = status; + } template <typename T, uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> void push_back_recv_packet( - uhd::transport::vrt::if_packet_info_t& ifpi, - const std::vector<T>& otw_data - ); + uhd::transport::vrt::if_packet_info_t& ifpi, const std::vector<T>& otw_data); template <uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> void push_back_inline_message_packet( - uhd::transport::vrt::if_packet_info_t& ifpi, - const uint32_t message - ); + uhd::transport::vrt::if_packet_info_t& ifpi, const uint32_t message); template <uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> void push_back_flow_ctrl_packet( uhd::transport::vrt::if_packet_info_t::packet_type_t type, uint32_t packet_count, - uint32_t byte_count - ); + uint32_t byte_count); template <uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> - void pop_send_packet( - uhd::transport::vrt::if_packet_info_t &ifpi - ); + void pop_send_packet(uhd::transport::vrt::if_packet_info_t& ifpi); - private: +private: std::list<boost::shared_array<uint8_t>> _tx_mems; std::list<size_t> _tx_lens; @@ -136,27 +147,23 @@ class mock_zero_copy : public uhd::transport::zero_copy_if { bool _reuse_recv_memory = false; bool _reuse_send_memory = false; - }; template <typename T, uhd::endianness_t endianness> void mock_zero_copy::push_back_recv_packet( - uhd::transport::vrt::if_packet_info_t& ifpi, - const std::vector<T>& otw_data -) { + uhd::transport::vrt::if_packet_info_t& ifpi, const std::vector<T>& otw_data) +{ using namespace uhd::transport; UHD_ASSERT_THROW( - ifpi.num_payload_words32 * sizeof(uint32_t) - == otw_data.size() * sizeof(T)); + ifpi.num_payload_words32 * sizeof(uint32_t) == otw_data.size() * sizeof(T)); const size_t max_hdr_len = - _link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR ? - vrt::chdr::max_if_hdr_words64*sizeof(uint64_t) : - (vrt::max_if_hdr_words32 + 1/*tlr*/)*sizeof(uint32_t); + _link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR + ? vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t) + : (vrt::max_if_hdr_words32 + 1 /*tlr*/) * sizeof(uint32_t); - const size_t max_pkt_len = - ifpi.num_payload_words32*sizeof(uint32_t)+max_hdr_len; + const size_t max_pkt_len = ifpi.num_payload_words32 * sizeof(uint32_t) + max_hdr_len; UHD_ASSERT_THROW(max_pkt_len <= _recv_frame_size); @@ -168,15 +175,13 @@ void mock_zero_copy::push_back_recv_packet( if (endianness == uhd::ENDIANNESS_BIG) { if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { uhd::transport::vrt::chdr::if_hdr_pack_be(rx_buff_ptr, ifpi); - } - else { + } else { uhd::transport::vrt::if_hdr_pack_be(rx_buff_ptr, ifpi); } } else { if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { uhd::transport::vrt::chdr::if_hdr_pack_le(rx_buff_ptr, ifpi); - } - else { + } else { uhd::transport::vrt::if_hdr_pack_le(rx_buff_ptr, ifpi); } } @@ -184,42 +189,37 @@ void mock_zero_copy::push_back_recv_packet( // Copy data uint32_t* data_ptr = (rx_buff_ptr + ifpi.num_header_words32); std::copy(otw_data.begin(), otw_data.end(), reinterpret_cast<T*>(data_ptr)); - _rx_lens.push_back(ifpi.num_packet_words32*sizeof(uint32_t)); + _rx_lens.push_back(ifpi.num_packet_words32 * sizeof(uint32_t)); } template <uhd::endianness_t endianness> void mock_zero_copy::push_back_inline_message_packet( - uhd::transport::vrt::if_packet_info_t& ifpi, - const uint32_t message -) { - const std::vector<uint32_t> data { message | uhd::byteswap(message) }; + uhd::transport::vrt::if_packet_info_t& ifpi, const uint32_t message) +{ + const std::vector<uint32_t> data{message | uhd::byteswap(message)}; push_back_recv_packet<uint32_t, endianness>(ifpi, data); } template <uhd::endianness_t endianness> -void mock_zero_copy::pop_send_packet( - uhd::transport::vrt::if_packet_info_t &ifpi -) { +void mock_zero_copy::pop_send_packet(uhd::transport::vrt::if_packet_info_t& ifpi) +{ using namespace uhd::transport; - ifpi.num_packet_words32 = _tx_lens.front()/sizeof(uint32_t); + ifpi.num_packet_words32 = _tx_lens.front() / sizeof(uint32_t); - uint32_t* tx_buff_ptr = reinterpret_cast<uint32_t *>(_tx_mems.front().get()); + uint32_t* tx_buff_ptr = reinterpret_cast<uint32_t*>(_tx_mems.front().get()); if (endianness == uhd::ENDIANNESS_BIG) { if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { uhd::transport::vrt::chdr::if_hdr_unpack_be(tx_buff_ptr, ifpi); - } - else { + } else { uhd::transport::vrt::if_hdr_unpack_be(tx_buff_ptr, ifpi); } - } - else { + } else { if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { uhd::transport::vrt::chdr::if_hdr_unpack_le(tx_buff_ptr, ifpi); - } - else { + } else { uhd::transport::vrt::if_hdr_unpack_le(tx_buff_ptr, ifpi); } } @@ -231,14 +231,12 @@ template <uhd::endianness_t endianness> void mock_zero_copy::push_back_flow_ctrl_packet( uhd::transport::vrt::if_packet_info_t::packet_type_t type, uint32_t packet_count, - uint32_t byte_count -) + uint32_t byte_count) { using namespace uhd::transport; - UHD_ASSERT_THROW( - type == vrt::if_packet_info_t::PACKET_TYPE_FC or - type == vrt::if_packet_info_t::PACKET_TYPE_ACK); + UHD_ASSERT_THROW(type == vrt::if_packet_info_t::PACKET_TYPE_FC + or type == vrt::if_packet_info_t::PACKET_TYPE_ACK); // Only implemented for chdr packets currently UHD_ASSERT_THROW(_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR); @@ -246,18 +244,17 @@ void mock_zero_copy::push_back_flow_ctrl_packet( const size_t packet_len_in_words32 = 2; vrt::if_packet_info_t ifpi; - ifpi.packet_type = type; + ifpi.packet_type = type; ifpi.num_payload_words32 = packet_len_in_words32; - ifpi.num_payload_bytes = ifpi.num_payload_words32*sizeof(uint32_t); - ifpi.has_tsf = false; + ifpi.num_payload_bytes = ifpi.num_payload_words32 * sizeof(uint32_t); + ifpi.has_tsf = false; std::vector<uint32_t> data(packet_len_in_words32, 0); if (endianness == uhd::ENDIANNESS_BIG) { data[0] = uhd::ntohx(packet_count); data[1] = uhd::ntohx(byte_count); - } - else { + } else { data[0] = uhd::wtohx(packet_count); data[1] = uhd::wtohx(byte_count); } diff --git a/host/tests/config_parser_test.cpp b/host/tests/config_parser_test.cpp index ef1686a11..2016776a7 100644 --- a/host/tests/config_parser_test.cpp +++ b/host/tests/config_parser_test.cpp @@ -5,93 +5,68 @@ // #include <uhdlib/utils/config_parser.hpp> -#include <boost/test/unit_test.hpp> #include <boost/assign/list_of.hpp> -#include <fstream> +#include <boost/test/unit_test.hpp> #include <cstdio> +#include <fstream> const std::string INI1_FILENAME = "test1.ini"; -const std::string INI1 = - "[section1]\n" - "key1=value1\n" - "key2=4\n" - "\n" - "; This is a comment\n" - "[section2]\n" - "key3=value with spaces\n" - "key4= leading and trailing spaces \n" -; +const std::string INI1 = "[section1]\n" + "key1=value1\n" + "key2=4\n" + "\n" + "; This is a comment\n" + "[section2]\n" + "key3=value with spaces\n" + "key4= leading and trailing spaces \n"; const std::string INI2_FILENAME = "test2.ini"; -const std::string INI2 = - "[section2]\n" - "key3=value with even more spaces\n" - "\n" - "[section3]\n" - "key4=\"with quotes\"\n"; +const std::string INI2 = "[section2]\n" + "key3=value with even more spaces\n" + "\n" + "[section3]\n" + "key4=\"with quotes\"\n"; namespace { - //! Create files that can be read by the CUT - void make_config_parsers() - { - std::ofstream ini1(INI1_FILENAME); - ini1 << INI1 << std::endl; - ini1.close(); - std::ofstream ini2(INI2_FILENAME); - ini2 << INI2 << std::endl; - ini2.close(); - } +//! Create files that can be read by the CUT +void make_config_parsers() +{ + std::ofstream ini1(INI1_FILENAME); + ini1 << INI1 << std::endl; + ini1.close(); + std::ofstream ini2(INI2_FILENAME); + ini2 << INI2 << std::endl; + ini2.close(); +} - //! Tidy up after us - void cleanup_config_parsers() - { - std::remove(INI1_FILENAME.c_str()); - std::remove(INI2_FILENAME.c_str()); - } +//! Tidy up after us +void cleanup_config_parsers() +{ + std::remove(INI1_FILENAME.c_str()); + std::remove(INI2_FILENAME.c_str()); } +} // namespace -BOOST_AUTO_TEST_CASE(test_config_parser){ +BOOST_AUTO_TEST_CASE(test_config_parser) +{ make_config_parsers(); uhd::config_parser I(INI1_FILENAME); BOOST_CHECK_EQUAL(I.sections().size(), 2); BOOST_CHECK_EQUAL(I.options("section1").size(), 2); + BOOST_CHECK_EQUAL(I.get<std::string>("section1", "key1"), "value1"); + BOOST_CHECK_EQUAL(I.get<int>("section1", "key2"), 4); + BOOST_CHECK_EQUAL(I.get<std::string>("section2", "key3"), "value with spaces"); BOOST_CHECK_EQUAL( - I.get<std::string>("section1", "key1"), - "value1" - ); + I.get<std::string>("section2", "key4"), "leading and trailing spaces"); BOOST_CHECK_EQUAL( - I.get<int>("section1", "key2"), - 4 - ); - BOOST_CHECK_EQUAL( - I.get<std::string>("section2", "key3"), - "value with spaces" - ); - BOOST_CHECK_EQUAL( - I.get<std::string>("section2", "key4"), - "leading and trailing spaces" - ); - BOOST_CHECK_EQUAL( - I.get<std::string>("section2", "non_existent_key", "default"), - "default" - ); + I.get<std::string>("section2", "non_existent_key", "default"), "default"); BOOST_REQUIRE_THROW( - I.get<std::string>("section2", "non_existent_key"), - uhd::key_error - ); + I.get<std::string>("section2", "non_existent_key"), uhd::key_error); I.read_file(INI2_FILENAME); BOOST_CHECK_EQUAL( - I.get<std::string>("section2", "key3"), - "value with even more spaces" - ); - BOOST_CHECK_EQUAL( - I.get<std::string>("section1", "key1"), - "value1" - ); - BOOST_CHECK_EQUAL( - I.get<std::string>("section3", "key4"), - "\"with quotes\"" - ); + I.get<std::string>("section2", "key3"), "value with even more spaces"); + BOOST_CHECK_EQUAL(I.get<std::string>("section1", "key1"), "value1"); + BOOST_CHECK_EQUAL(I.get<std::string>("section3", "key4"), "\"with quotes\""); cleanup_config_parsers(); } diff --git a/host/tests/constrained_device_args_test.cpp b/host/tests/constrained_device_args_test.cpp index 318315739..2fe7e5c16 100644 --- a/host/tests/constrained_device_args_test.cpp +++ b/host/tests/constrained_device_args_test.cpp @@ -4,101 +4,93 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhdlib/usrp/constrained_device_args.hpp> +#include <boost/test/unit_test.hpp> #include <iostream> using uhd::usrp::constrained_device_args_t; namespace { - enum test_enum_t { VALUE1, VALUE2, VALUE3=4 }; +enum test_enum_t { VALUE1, VALUE2, VALUE3 = 4 }; - static constexpr double MAX_DOUBLE_ARG = 1e6; - static constexpr double MIN_DOUBLE_ARG = 0.125; +static constexpr double MAX_DOUBLE_ARG = 1e6; +static constexpr double MIN_DOUBLE_ARG = 0.125; - static constexpr double DEFAULT_DOUBLE_ARG = 2.25; - static constexpr size_t DEFAULT_SIZE_T_ARG = 42; - static constexpr bool DEFAULT_BOOL_ARG = true; - static constexpr test_enum_t DEFAULT_ENUM_ARG = VALUE1; +static constexpr double DEFAULT_DOUBLE_ARG = 2.25; +static constexpr size_t DEFAULT_SIZE_T_ARG = 42; +static constexpr bool DEFAULT_BOOL_ARG = true; +static constexpr test_enum_t DEFAULT_ENUM_ARG = VALUE1; - class test_device_args_t : public constrained_device_args_t +class test_device_args_t : public constrained_device_args_t +{ +public: + test_device_args_t() {} + test_device_args_t(const std::string& dev_args) { - public: - test_device_args_t() {} - test_device_args_t(const std::string& dev_args) { parse(dev_args); } + parse(dev_args); + } - double get_double_arg() const { - return _double_arg.get(); - } - size_t get_size_t_arg() const { - return _size_t_arg.get(); - } - bool get_bool_arg() const { - return _bool_arg.get(); - } - test_enum_t get_enum_arg() const { - return _enum_arg.get(); - } + double get_double_arg() const + { + return _double_arg.get(); + } + size_t get_size_t_arg() const + { + return _size_t_arg.get(); + } + bool get_bool_arg() const + { + return _bool_arg.get(); + } + test_enum_t get_enum_arg() const + { + return _enum_arg.get(); + } - inline virtual std::string to_string() const { - return _double_arg.to_string() + ", " + - _size_t_arg.to_string() + ", " + - _bool_arg.to_string() + ", " + - _enum_arg.to_string(); - } - private: - virtual void _parse(const uhd::device_addr_t& dev_args) { - if (dev_args.has_key(_double_arg.key())) - _double_arg.parse(dev_args[_double_arg.key()]); - if (dev_args.has_key(_size_t_arg.key())) - _size_t_arg.parse(dev_args[_size_t_arg.key()]); - if (dev_args.has_key(_bool_arg.key())) - _bool_arg.parse(dev_args[_bool_arg.key()]); - if (dev_args.has_key(_enum_arg.key())) - _enum_arg.parse(dev_args[_enum_arg.key()]); - _enforce_range(_double_arg, MIN_DOUBLE_ARG, MAX_DOUBLE_ARG); - } + inline virtual std::string to_string() const + { + return _double_arg.to_string() + ", " + _size_t_arg.to_string() + ", " + + _bool_arg.to_string() + ", " + _enum_arg.to_string(); + } - constrained_device_args_t::num_arg<double> _double_arg - {"double_arg", DEFAULT_DOUBLE_ARG}; - constrained_device_args_t::num_arg<size_t> _size_t_arg - {"size_t_arg", DEFAULT_SIZE_T_ARG}; - constrained_device_args_t::bool_arg _bool_arg - {"bool_arg", DEFAULT_BOOL_ARG}; - constrained_device_args_t::enum_arg<test_enum_t> _enum_arg - {"enum_arg", DEFAULT_ENUM_ARG, - {{"value1", VALUE1}, {"value2", VALUE2}, {"VALUE3", VALUE3}}}; - }; +private: + virtual void _parse(const uhd::device_addr_t& dev_args) + { + if (dev_args.has_key(_double_arg.key())) + _double_arg.parse(dev_args[_double_arg.key()]); + if (dev_args.has_key(_size_t_arg.key())) + _size_t_arg.parse(dev_args[_size_t_arg.key()]); + if (dev_args.has_key(_bool_arg.key())) + _bool_arg.parse(dev_args[_bool_arg.key()]); + if (dev_args.has_key(_enum_arg.key())) + _enum_arg.parse(dev_args[_enum_arg.key()]); + _enforce_range(_double_arg, MIN_DOUBLE_ARG, MAX_DOUBLE_ARG); + } -} + constrained_device_args_t::num_arg<double> _double_arg{ + "double_arg", DEFAULT_DOUBLE_ARG}; + constrained_device_args_t::num_arg<size_t> _size_t_arg{ + "size_t_arg", DEFAULT_SIZE_T_ARG}; + constrained_device_args_t::bool_arg _bool_arg{"bool_arg", DEFAULT_BOOL_ARG}; + constrained_device_args_t::enum_arg<test_enum_t> _enum_arg{"enum_arg", + DEFAULT_ENUM_ARG, + {{"value1", VALUE1}, {"value2", VALUE2}, {"VALUE3", VALUE3}}}; +}; -BOOST_AUTO_TEST_CASE(test_constrained_device_args) { +} // namespace + +BOOST_AUTO_TEST_CASE(test_constrained_device_args) +{ test_device_args_t test_dev_args("double_arg=3.5,bool_arg=0,foo=bar"); BOOST_CHECK_EQUAL(test_dev_args.get_double_arg(), 3.5); - BOOST_CHECK_EQUAL( - test_dev_args.get_size_t_arg(), - DEFAULT_SIZE_T_ARG - ); + BOOST_CHECK_EQUAL(test_dev_args.get_size_t_arg(), DEFAULT_SIZE_T_ARG); BOOST_CHECK_EQUAL(test_dev_args.get_bool_arg(), false); - BOOST_CHECK_EQUAL( - test_dev_args.get_enum_arg(), - DEFAULT_ENUM_ARG - ); - BOOST_REQUIRE_THROW( - test_dev_args.parse("double_arg=2e6"), - uhd::value_error - ); // Note: test_dev_args is now in a bad state until we fix it! - test_dev_args.parse("double_arg=2.6"), - test_dev_args.parse("enum_arg=vaLue2"); - BOOST_CHECK_EQUAL( - test_dev_args.get_enum_arg(), - VALUE2 - ); + BOOST_CHECK_EQUAL(test_dev_args.get_enum_arg(), DEFAULT_ENUM_ARG); + BOOST_REQUIRE_THROW(test_dev_args.parse("double_arg=2e6"), + uhd::value_error); // Note: test_dev_args is now in a bad state until we fix it! + test_dev_args.parse("double_arg=2.6"), test_dev_args.parse("enum_arg=vaLue2"); + BOOST_CHECK_EQUAL(test_dev_args.get_enum_arg(), VALUE2); test_dev_args.parse("enum_arg=VALUE3"); - BOOST_CHECK_EQUAL( - test_dev_args.get_enum_arg(), - VALUE3 - ); + BOOST_CHECK_EQUAL(test_dev_args.get_enum_arg(), VALUE3); } - diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index 862e02073..67409e310 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -6,52 +6,54 @@ // #include <uhd/convert.hpp> -#include <boost/test/unit_test.hpp> #include <stdint.h> +#include <boost/test/unit_test.hpp> #include <complex> -#include <vector> #include <cstdlib> #include <iostream> +#include <vector> using namespace uhd; -//typedefs for complex types +// typedefs for complex types typedef std::complex<int16_t> sc16_t; typedef std::complex<float> fc32_t; typedef std::complex<double> fc64_t; -#define MY_CHECK_CLOSE(a, b, f) { \ - BOOST_CHECK_MESSAGE(std::abs((a)-(b)) < f, "\n\t" << #a << " (" << (a) << ") error " << #b << " (" << (b) << ")"); \ -} +#define MY_CHECK_CLOSE(a, b, f) \ + { \ + BOOST_CHECK_MESSAGE(std::abs((a) - (b)) < f, \ + "\n\t" << #a << " (" << (a) << ") error " << #b << " (" << (b) << ")"); \ + } /*********************************************************************** * Loopback runner: * convert input buffer into intermediate buffer * convert intermediate buffer into output buffer **********************************************************************/ -template <typename Range> static void loopback( - size_t nsamps, - convert::id_type &in_id, - convert::id_type &out_id, - const Range &input, - Range &output, - const int prio_in = -1, - const int prio_out = -1 -){ - //make this buffer large enough for all test types +template <typename Range> +static void loopback(size_t nsamps, + convert::id_type& in_id, + convert::id_type& out_id, + const Range& input, + Range& output, + const int prio_in = -1, + const int prio_out = -1) +{ + // make this buffer large enough for all test types std::vector<uint64_t> interm(nsamps); - std::vector<const void *> input0(1, &input[0]), input1(1, &interm[0]); - std::vector<void *> output0(1, &interm[0]), output1(1, &output[0]); + std::vector<const void*> input0(1, &input[0]), input1(1, &interm[0]); + std::vector<void*> output0(1, &interm[0]), output1(1, &output[0]); - //convert to intermediate type + // convert to intermediate type convert::converter::sptr c0 = convert::get_converter(in_id, prio_in)(); c0->set_scalar(32767.); c0->conv(input0, output0, nsamps); - //convert back to host type + // convert back to host type convert::converter::sptr c1 = convert::get_converter(out_id, prio_out)(); - c1->set_scalar(1/32767.); + c1->set_scalar(1 / 32767.); c1->conv(input1, output1, nsamps); } @@ -59,46 +61,51 @@ template <typename Range> static void loopback( * Test short conversion **********************************************************************/ static void test_convert_types_sc16( - size_t nsamps, convert::id_type &id, const int extra_div = 1, int mask = 0xffff -){ - //fill the input samples + size_t nsamps, convert::id_type& id, const int extra_div = 1, int mask = 0xffff) +{ + // fill the input samples std::vector<sc16_t> input(nsamps), output(nsamps); - for(sc16_t &in: input) in = sc16_t( - short((float((std::rand())/(double(RAND_MAX)/2)) - 1)*32767/extra_div) & mask, - short((float((std::rand())/(double(RAND_MAX)/2)) - 1)*32767/extra_div) & mask - ); - - //run the loopback and test - convert::id_type in_id = id; + for (sc16_t& in : input) + in = sc16_t( + short((float((std::rand()) / (double(RAND_MAX) / 2)) - 1) * 32767 / extra_div) + & mask, + short((float((std::rand()) / (double(RAND_MAX) / 2)) - 1) * 32767 / extra_div) + & mask); + + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( + input.begin(), input.end(), output.begin(), output.end()); } -BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16){ +BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16) +{ convert::id_type id; - id.input_format = "sc16"; - id.num_inputs = 1; + id.input_format = "sc16"; + id.num_inputs = 1; id.output_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_sc16(nsamps, id); } } -BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){ +BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16) +{ convert::id_type id; - id.input_format = "sc16"; - id.num_inputs = 1; + id.input_format = "sc16"; + id.num_inputs = 1; id.output_format = "sc16_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_sc16(nsamps, id); } } @@ -108,90 +115,90 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){ **********************************************************************/ template <typename data_type> static void test_convert_types_for_floats( - size_t nsamps, convert::id_type &id, const double extra_scale = 1.0 -){ + size_t nsamps, convert::id_type& id, const double extra_scale = 1.0) +{ typedef typename data_type::value_type value_type; - //fill the input samples + // fill the input samples std::vector<data_type> input(nsamps), output(nsamps); - for(data_type &in: input) in = data_type( - ((std::rand()/(value_type(RAND_MAX)/2)) - 1)*float(extra_scale), - ((std::rand()/(value_type(RAND_MAX)/2)) - 1)*float(extra_scale) - ); + for (data_type& in : input) + in = data_type( + ((std::rand() / (value_type(RAND_MAX) / 2)) - 1) * float(extra_scale), + ((std::rand() / (value_type(RAND_MAX) / 2)) - 1) * float(extra_scale)); - //run the loopback and test - convert::id_type in_id = id; + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); - //make a list of all prio: best/generic combos + // make a list of all prio: best/generic combos typedef std::pair<int, int> int_pair_t; const std::vector<int_pair_t> prios{ - int_pair_t(0, 0), - int_pair_t(-1, 0), - int_pair_t(0, -1), - int_pair_t(-1, -1) - }; - - //loopback foreach prio combo (generic vs best) - for (const auto &prio : prios) { + int_pair_t(0, 0), int_pair_t(-1, 0), int_pair_t(0, -1), int_pair_t(-1, -1)}; + + // loopback foreach prio combo (generic vs best) + for (const auto& prio : prios) { loopback(nsamps, in_id, out_id, input, output, prio.first, prio.second); - for (size_t i = 0; i < nsamps; i++){ - MY_CHECK_CLOSE(input[i].real(), output[i].real(), value_type(1./(1 << 14))); - MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), value_type(1./(1 << 14))); + for (size_t i = 0; i < nsamps; i++) { + MY_CHECK_CLOSE(input[i].real(), output[i].real(), value_type(1. / (1 << 14))); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), value_type(1. / (1 << 14))); } } } -BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32) +{ convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_for_floats<fc32_t>(nsamps, id); } } -BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32) +{ convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "sc16_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_for_floats<fc32_t>(nsamps, id); } } -BOOST_AUTO_TEST_CASE(test_convert_types_be_fc64){ +BOOST_AUTO_TEST_CASE(test_convert_types_be_fc64) +{ convert::id_type id; - id.input_format = "fc64"; - id.num_inputs = 1; + id.input_format = "fc64"; + id.num_inputs = 1; id.output_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_for_floats<fc64_t>(nsamps, id); } } -BOOST_AUTO_TEST_CASE(test_convert_types_le_fc64){ +BOOST_AUTO_TEST_CASE(test_convert_types_le_fc64) +{ convert::id_type id; - id.input_format = "fc64"; - id.num_inputs = 1; + id.input_format = "fc64"; + id.num_inputs = 1; id.output_format = "sc16_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_for_floats<fc64_t>(nsamps, id); } } @@ -200,53 +207,57 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_fc64){ * Test float to/from sc12 conversion loopback **********************************************************************/ -BOOST_AUTO_TEST_CASE(test_convert_types_le_sc12_with_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_le_sc12_with_fc32) +{ convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "sc12_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ - test_convert_types_for_floats<fc32_t>(nsamps, id, 1./16); + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { + test_convert_types_for_floats<fc32_t>(nsamps, id, 1. / 16); } } -BOOST_AUTO_TEST_CASE(test_convert_types_be_sc12_with_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_be_sc12_with_fc32) +{ convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "sc12_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ - test_convert_types_for_floats<fc32_t>(nsamps, id, 1./16); + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { + test_convert_types_for_floats<fc32_t>(nsamps, id, 1. / 16); } } -BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16_and_sc12){ +BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16_and_sc12) +{ convert::id_type id; id.input_format = "sc16"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc12_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_sc16(nsamps, id, 1, 0xfff0); } } -BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16_and_sc12){ +BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16_and_sc12) +{ convert::id_type id; id.input_format = "sc16"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; id.output_format = "sc12_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_sc16(nsamps, id, 1, 0xfff0); } } @@ -255,28 +266,30 @@ BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16_and_sc12){ * Test float to/from fc32 conversion loopback **********************************************************************/ -BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32_with_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32_with_fc32) +{ convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "fc32_item32_le"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_for_floats<fc32_t>(nsamps, id); } } -BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32_with_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32_with_fc32) +{ convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "fc32_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + // try various lengths to test edge cases + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_for_floats<fc32_t>(nsamps, id); } } @@ -284,149 +297,151 @@ BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32_with_fc32){ /*********************************************************************** * Test float to short conversion loopback **********************************************************************/ -BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){ +BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16) +{ convert::id_type in_id; - in_id.input_format = "fc32"; - in_id.num_inputs = 1; + in_id.input_format = "fc32"; + in_id.num_inputs = 1; in_id.output_format = "sc16_item32_le"; - in_id.num_outputs = 1; + in_id.num_outputs = 1; convert::id_type out_id; - out_id.input_format = "sc16_item32_le"; - out_id.num_inputs = 1; + out_id.input_format = "sc16_item32_le"; + out_id.num_inputs = 1; out_id.output_format = "sc16"; - out_id.num_outputs = 1; + out_id.num_outputs = 1; const size_t nsamps = 13; std::vector<fc32_t> input(nsamps); - for(fc32_t &in: input) in = fc32_t( - (std::rand()/(RAND_MAX/2.0)) - 1, - (std::rand()/(RAND_MAX/2.0)) - 1 - ); + for (fc32_t& in : input) + in = fc32_t( + (std::rand() / (RAND_MAX / 2.0)) - 1, (std::rand() / (RAND_MAX / 2.0)) - 1); std::vector<uint32_t> interm(nsamps); std::vector<sc16_t> output(nsamps); - std::vector<const void *> input0(1, &input[0]), input1(1, &interm[0]); - std::vector<void *> output0(1, &interm[0]), output1(1, &output[0]); + std::vector<const void*> input0(1, &input[0]), input1(1, &interm[0]); + std::vector<void*> output0(1, &interm[0]), output1(1, &output[0]); - //convert float to intermediate + // convert float to intermediate convert::converter::sptr c0 = convert::get_converter(in_id)(); c0->set_scalar(32767.); c0->conv(input0, output0, nsamps); - //convert intermediate to short + // convert intermediate to short convert::converter::sptr c1 = convert::get_converter(out_id)(); - c1->set_scalar(1/32767.); + c1->set_scalar(1 / 32767.); c1->conv(input1, output1, nsamps); - //test that the inputs and outputs match - for (size_t i = 0; i < nsamps; i++){ - MY_CHECK_CLOSE(input[i].real(), output[i].real()/float(32767), float(0.01)); - MY_CHECK_CLOSE(input[i].imag(), output[i].imag()/float(32767), float(0.01)); + // test that the inputs and outputs match + for (size_t i = 0; i < nsamps; i++) { + MY_CHECK_CLOSE(input[i].real(), output[i].real() / float(32767), float(0.01)); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag() / float(32767), float(0.01)); } } /*********************************************************************** * Test short to float conversion loopback **********************************************************************/ -BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32) +{ convert::id_type in_id; - in_id.input_format = "sc16"; - in_id.num_inputs = 1; + in_id.input_format = "sc16"; + in_id.num_inputs = 1; in_id.output_format = "sc16_item32_le"; - in_id.num_outputs = 1; + in_id.num_outputs = 1; convert::id_type out_id; - out_id.input_format = "sc16_item32_le"; - out_id.num_inputs = 1; + out_id.input_format = "sc16_item32_le"; + out_id.num_inputs = 1; out_id.output_format = "fc32"; - out_id.num_outputs = 1; + out_id.num_outputs = 1; const size_t nsamps = 13; std::vector<sc16_t> input(nsamps); - for(sc16_t &in: input) in = sc16_t( - std::rand()-(RAND_MAX/2), - std::rand()-(RAND_MAX/2) - ); + for (sc16_t& in : input) + in = sc16_t(std::rand() - (RAND_MAX / 2), std::rand() - (RAND_MAX / 2)); std::vector<uint32_t> interm(nsamps); std::vector<fc32_t> output(nsamps); - std::vector<const void *> input0(1, &input[0]), input1(1, &interm[0]); - std::vector<void *> output0(1, &interm[0]), output1(1, &output[0]); + std::vector<const void*> input0(1, &input[0]), input1(1, &interm[0]); + std::vector<void*> output0(1, &interm[0]), output1(1, &output[0]); - //convert short to intermediate + // convert short to intermediate convert::converter::sptr c0 = convert::get_converter(in_id)(); c0->set_scalar(32767.); c0->conv(input0, output0, nsamps); - //convert intermediate to float + // convert intermediate to float convert::converter::sptr c1 = convert::get_converter(out_id)(); - c1->set_scalar(1/32767.); + c1->set_scalar(1 / 32767.); c1->conv(input1, output1, nsamps); - //test that the inputs and outputs match - for (size_t i = 0; i < nsamps; i++){ - MY_CHECK_CLOSE(input[i].real()/float(32767), output[i].real(), float(0.01)); - MY_CHECK_CLOSE(input[i].imag()/float(32767), output[i].imag(), float(0.01)); + // test that the inputs and outputs match + for (size_t i = 0; i < nsamps; i++) { + MY_CHECK_CLOSE(input[i].real() / float(32767), output[i].real(), float(0.01)); + MY_CHECK_CLOSE(input[i].imag() / float(32767), output[i].imag(), float(0.01)); } } /*********************************************************************** * Test sc8 conversions **********************************************************************/ -BOOST_AUTO_TEST_CASE(test_convert_types_fc64_and_sc8){ +BOOST_AUTO_TEST_CASE(test_convert_types_fc64_and_sc8) +{ convert::id_type id; id.input_format = "fc64"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc8_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ - test_convert_types_for_floats<fc64_t>(nsamps, id, 1./256); + for (size_t nsamps = 1; nsamps < 16; nsamps++) { + test_convert_types_for_floats<fc64_t>(nsamps, id, 1. / 256); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc8_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ - test_convert_types_for_floats<fc64_t>(nsamps, id, 1./256); + for (size_t nsamps = 1; nsamps < 16; nsamps++) { + test_convert_types_for_floats<fc64_t>(nsamps, id, 1. / 256); } } -BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_sc8){ +BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_sc8) +{ convert::id_type id; id.input_format = "fc32"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc8_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ - test_convert_types_for_floats<fc32_t>(nsamps, id, 1./256); + for (size_t nsamps = 1; nsamps < 16; nsamps++) { + test_convert_types_for_floats<fc32_t>(nsamps, id, 1. / 256); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc8_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ - test_convert_types_for_floats<fc32_t>(nsamps, id, 1./256); + for (size_t nsamps = 1; nsamps < 16; nsamps++) { + test_convert_types_for_floats<fc32_t>(nsamps, id, 1. / 256); } } -BOOST_AUTO_TEST_CASE(test_convert_types_sc16_and_sc8){ +BOOST_AUTO_TEST_CASE(test_convert_types_sc16_and_sc8) +{ convert::id_type id; id.input_format = "sc16"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc8_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_sc16(nsamps, id, 256); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "sc8_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_sc16(nsamps, id, 256); } } @@ -434,39 +449,41 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_and_sc8){ /*********************************************************************** * Test u8 conversion **********************************************************************/ -static void test_convert_types_u8( - size_t nsamps, convert::id_type &id -){ - //fill the input samples +static void test_convert_types_u8(size_t nsamps, convert::id_type& id) +{ + // fill the input samples std::vector<uint8_t> input(nsamps), output(nsamps); - for(uint8_t &in: input) in = uint8_t(std::rand() & 0xFF); - //uint32_t d = 48; - //for(uint8_t &in: input) in = d++; + for (uint8_t& in : input) + in = uint8_t(std::rand() & 0xFF); + // uint32_t d = 48; + // for(uint8_t &in: input) in = d++; - //run the loopback and test - convert::id_type in_id = id; + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( + input.begin(), input.end(), output.begin(), output.end()); } -BOOST_AUTO_TEST_CASE(test_convert_types_u8_and_u8){ +BOOST_AUTO_TEST_CASE(test_convert_types_u8_and_u8) +{ convert::id_type id; id.input_format = "u8"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "u8_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_u8(nsamps, id); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "u8_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_u8(nsamps, id); } } @@ -474,37 +491,39 @@ BOOST_AUTO_TEST_CASE(test_convert_types_u8_and_u8){ /*********************************************************************** * Test s8 conversion **********************************************************************/ -static void test_convert_types_s8( - size_t nsamps, convert::id_type &id -){ - //fill the input samples +static void test_convert_types_s8(size_t nsamps, convert::id_type& id) +{ + // fill the input samples std::vector<int8_t> input(nsamps), output(nsamps); - for(int8_t &in: input) in = int8_t(std::rand() & 0xFF); + for (int8_t& in : input) + in = int8_t(std::rand() & 0xFF); - //run the loopback and test - convert::id_type in_id = id; + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( + input.begin(), input.end(), output.begin(), output.end()); } -BOOST_AUTO_TEST_CASE(test_convert_types_s8_and_s8){ +BOOST_AUTO_TEST_CASE(test_convert_types_s8_and_s8) +{ convert::id_type id; id.input_format = "s8"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "s8_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_s8(nsamps, id); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "s8_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_s8(nsamps, id); } } @@ -512,37 +531,39 @@ BOOST_AUTO_TEST_CASE(test_convert_types_s8_and_s8){ /*********************************************************************** * Test s16 conversion **********************************************************************/ -static void test_convert_types_s16( - size_t nsamps, convert::id_type &id -){ - //fill the input samples +static void test_convert_types_s16(size_t nsamps, convert::id_type& id) +{ + // fill the input samples std::vector<int16_t> input(nsamps), output(nsamps); - for(int16_t &in: input) in = int16_t(std::rand() & 0xFFFF); + for (int16_t& in : input) + in = int16_t(std::rand() & 0xFFFF); - //run the loopback and test - convert::id_type in_id = id; + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( + input.begin(), input.end(), output.begin(), output.end()); } -BOOST_AUTO_TEST_CASE(test_convert_types_s16_and_s16){ +BOOST_AUTO_TEST_CASE(test_convert_types_s16_and_s16) +{ convert::id_type id; id.input_format = "s16"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "s16_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_s16(nsamps, id); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "s16_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_s16(nsamps, id); } } @@ -550,43 +571,42 @@ BOOST_AUTO_TEST_CASE(test_convert_types_s16_and_s16){ /*********************************************************************** * Test fc32 -> fc32 conversion **********************************************************************/ -static void test_convert_types_fc32( - size_t nsamps, convert::id_type &id -){ - //fill the input samples - std::vector< std::complex<float> > input(nsamps), output(nsamps); - for(fc32_t &in: input) in = fc32_t( - (std::rand()/float(RAND_MAX/2)) - 1, - (std::rand()/float(RAND_MAX/2)) - 1 - ); - - //run the loopback and test - convert::id_type in_id = id; +static void test_convert_types_fc32(size_t nsamps, convert::id_type& id) +{ + // fill the input samples + std::vector<std::complex<float>> input(nsamps), output(nsamps); + for (fc32_t& in : input) + in = fc32_t((std::rand() / float(RAND_MAX / 2)) - 1, + (std::rand() / float(RAND_MAX / 2)) - 1); + + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - for (size_t i = 0; i < nsamps; i++){ - MY_CHECK_CLOSE(input[i].real(), output[i].real(), float(1./(1 << 16))); - MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), float(1./(1 << 16))); + for (size_t i = 0; i < nsamps; i++) { + MY_CHECK_CLOSE(input[i].real(), output[i].real(), float(1. / (1 << 16))); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), float(1. / (1 << 16))); } } -BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_fc32){ +BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_fc32) +{ convert::id_type id; id.input_format = "fc32"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "fc32_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_fc32(nsamps, id); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "fc32_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_fc32(nsamps, id); } } @@ -594,39 +614,40 @@ BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_fc32){ /*********************************************************************** * Test f32 -> f32 conversion **********************************************************************/ -static void test_convert_types_f32( - size_t nsamps, convert::id_type &id -){ - //fill the input samples +static void test_convert_types_f32(size_t nsamps, convert::id_type& id) +{ + // fill the input samples std::vector<float> input(nsamps), output(nsamps); - for(float &in: input) in = float((float(std::rand())/float(RAND_MAX/2)) - 1); + for (float& in : input) + in = float((float(std::rand()) / float(RAND_MAX / 2)) - 1); - //run the loopback and test - convert::id_type in_id = id; + // run the loopback and test + convert::id_type in_id = id; convert::id_type out_id = id; std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - for (size_t i = 0; i < nsamps; i++){ - MY_CHECK_CLOSE(input[i], output[i], float(1./(1 << 16))); + for (size_t i = 0; i < nsamps; i++) { + MY_CHECK_CLOSE(input[i], output[i], float(1. / (1 << 16))); } } -BOOST_AUTO_TEST_CASE(test_convert_types_f32_and_f32){ +BOOST_AUTO_TEST_CASE(test_convert_types_f32_and_f32) +{ convert::id_type id; id.input_format = "f32"; - id.num_inputs = 1; - id.num_outputs = 1; + id.num_inputs = 1; + id.num_outputs = 1; - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "f32_item32_le"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_f32(nsamps, id); } - //try various lengths to test edge cases + // try various lengths to test edge cases id.output_format = "f32_item32_be"; - for (size_t nsamps = 1; nsamps < 16; nsamps++){ + for (size_t nsamps = 1; nsamps < 16; nsamps++) { test_convert_types_f32(nsamps, id); } } diff --git a/host/tests/device3_test.cpp b/host/tests/device3_test.cpp index 71b3225e1..43f5fe45b 100644 --- a/host/tests/device3_test.cpp +++ b/host/tests/device3_test.cpp @@ -6,8 +6,8 @@ // -#include "mock_zero_copy.hpp" #include "mock_ctrl_iface_impl.hpp" +#include "mock_zero_copy.hpp" #include <uhd/device3.hpp> #include <uhd/property_tree.hpp> #include <uhd/rfnoc/block_ctrl.hpp> @@ -20,17 +20,17 @@ #include <iostream> - using namespace uhd; using namespace uhd::rfnoc; using namespace uhd::transport::vrt; -using uhd::transport::managed_send_buffer; using uhd::transport::managed_recv_buffer; +using uhd::transport::managed_send_buffer; static const sid_t TEST_SID0 = 0x00000200; // 0.0.2.0 static const sid_t TEST_SID1 = 0x00000210; // 0.0.2.F -uhd::both_xports_t make_mock_transport(const uhd::sid_t& tx_sid) { +uhd::both_xports_t make_mock_transport(const uhd::sid_t& tx_sid) +{ uhd::both_xports_t xports; xports.send_sid = tx_sid; xports.recv_sid = tx_sid.reversed(); @@ -42,60 +42,59 @@ uhd::both_xports_t make_mock_transport(const uhd::sid_t& tx_sid) { } // Mock-device -class mock_device3_impl : public uhd::device3, public boost::enable_shared_from_this<mock_device3_impl> +class mock_device3_impl : public uhd::device3, + public boost::enable_shared_from_this<mock_device3_impl> { - public: +public: mock_device3_impl() { _tree = uhd::property_tree::make(); _tree->create<std::string>("/name").set("Test Mock-Device3"); // We can re-use this: std::map<size_t, ctrl_iface::sptr> ctrl_ifaces{ - {0, ctrl_iface::sptr(new mock_ctrl_iface_impl())} - }; + {0, ctrl_iface::sptr(new mock_ctrl_iface_impl())}}; // Add two block controls: uhd::rfnoc::make_args_t make_args; - make_args.ctrl_ifaces = ctrl_ifaces; + make_args.ctrl_ifaces = ctrl_ifaces; make_args.base_address = TEST_SID0.get_dst(); make_args.device_index = 0; - make_args.tree = _tree; + make_args.tree = _tree; std::cout << "[MOCK] Generating block controls 1/2:" << std::endl; - _rfnoc_block_ctrl.push_back( block_ctrl_base::make(make_args) ); + _rfnoc_block_ctrl.push_back(block_ctrl_base::make(make_args)); std::cout << "[MOCK] Generating block controls 2/2:" << std::endl; make_args.base_address = TEST_SID1.get_dst(); - _rfnoc_block_ctrl.push_back( block_ctrl::make(make_args) ); + _rfnoc_block_ctrl.push_back(block_ctrl::make(make_args)); } - rx_streamer::sptr get_rx_stream(const stream_args_t &args) { + rx_streamer::sptr get_rx_stream(const stream_args_t& args) + { throw uhd::not_implemented_error(args.args.to_string()); } - tx_streamer::sptr get_tx_stream(const stream_args_t &args) { + tx_streamer::sptr get_tx_stream(const stream_args_t& args) + { throw uhd::not_implemented_error(args.args.to_string()); } - bool recv_async_msg(async_metadata_t &async_metadata, double timeout) { - throw uhd::not_implemented_error(str(boost::format("%d %f") % async_metadata.channel % timeout)); + bool recv_async_msg(async_metadata_t& async_metadata, double timeout) + { + throw uhd::not_implemented_error( + str(boost::format("%d %f") % async_metadata.channel % timeout)); } - rfnoc::graph::sptr create_graph(const std::string &name) + rfnoc::graph::sptr create_graph(const std::string& name) { sid_t async_sid(0); async_sid.set_dst_addr(2); auto async_xports = make_mock_transport(async_sid); - auto async_msg_handler = uhd::rfnoc::async_msg_handler::make( - async_xports.recv, + auto async_msg_handler = uhd::rfnoc::async_msg_handler::make(async_xports.recv, async_xports.send, async_xports.send_sid, - async_xports.endianness - ); - auto graph = boost::make_shared<uhd::rfnoc::graph_impl>( - name, - shared_from_this(), - async_msg_handler - ); + async_xports.endianness); + auto graph = boost::make_shared<uhd::rfnoc::graph_impl>( + name, shared_from_this(), async_msg_handler); return graph; } }; @@ -105,18 +104,21 @@ device3::sptr make_mock_device() return device3::sptr(new mock_device3_impl()); } -class mock_block_ctrl : public block_ctrl { +class mock_block_ctrl : public block_ctrl +{ int foo; }; -BOOST_AUTO_TEST_CASE(test_device3) { +BOOST_AUTO_TEST_CASE(test_device3) +{ device3::sptr my_device = make_mock_device(); std::cout << "Checking block 0..." << std::endl; BOOST_REQUIRE(my_device->find_blocks("Block").size()); std::cout << "Getting block 0..." << std::endl; - block_ctrl_base::sptr block0 = my_device->get_block_ctrl(my_device->find_blocks("Block")[0]); + block_ctrl_base::sptr block0 = + my_device->get_block_ctrl(my_device->find_blocks("Block")[0]); BOOST_REQUIRE(block0); BOOST_CHECK_EQUAL(block0->get_block_id(), "0/Block_0"); @@ -130,7 +132,8 @@ BOOST_AUTO_TEST_CASE(test_device3) { } -BOOST_AUTO_TEST_CASE(test_device3_graph) { +BOOST_AUTO_TEST_CASE(test_device3_graph) +{ auto my_device = make_mock_device(); std::cout << "Start device3 test graph.." << std::endl; std::cout << "Checking block 0..." << std::endl; @@ -153,28 +156,33 @@ BOOST_AUTO_TEST_CASE(test_device3_graph) { std::cout << "Connecting block_0 to block_1 ..." << std::endl; graph->connect(block_id_t("0/Block_0"), 0, block_id_t("0/Block_1"), 0); - BOOST_CHECK_EQUAL(block0->list_upstream_nodes().size(),0); - BOOST_CHECK_EQUAL(block0->list_downstream_nodes().size(),1); - BOOST_CHECK_EQUAL(block0->list_downstream_nodes()[0].lock()->unique_id(),"0/Block_1"); - BOOST_CHECK_EQUAL(block1->list_upstream_nodes().size(),1); - BOOST_CHECK_EQUAL(block1->list_downstream_nodes().size(),0); - BOOST_CHECK_EQUAL(block1->list_upstream_nodes()[0].lock()->unique_id(),"0/Block_0"); + BOOST_CHECK_EQUAL(block0->list_upstream_nodes().size(), 0); + BOOST_CHECK_EQUAL(block0->list_downstream_nodes().size(), 1); + BOOST_CHECK_EQUAL( + block0->list_downstream_nodes()[0].lock()->unique_id(), "0/Block_1"); + BOOST_CHECK_EQUAL(block1->list_upstream_nodes().size(), 1); + BOOST_CHECK_EQUAL(block1->list_downstream_nodes().size(), 0); + BOOST_CHECK_EQUAL(block1->list_upstream_nodes()[0].lock()->unique_id(), "0/Block_0"); } -BOOST_AUTO_TEST_CASE(test_device3_cast) { +BOOST_AUTO_TEST_CASE(test_device3_cast) +{ device3::sptr my_device = make_mock_device(); std::cout << "Getting block 0..." << std::endl; - block_ctrl::sptr block0 = my_device->get_block_ctrl<block_ctrl>(block_id_t("0/Block_0")); + block_ctrl::sptr block0 = + my_device->get_block_ctrl<block_ctrl>(block_id_t("0/Block_0")); BOOST_REQUIRE(block0); BOOST_CHECK_EQUAL(block0->get_block_id(), "0/Block_0"); std::cout << "Getting block 1..." << std::endl; - block_ctrl_base::sptr block1 = my_device->get_block_ctrl<block_ctrl>(block_id_t("0/Block_1")); + block_ctrl_base::sptr block1 = + my_device->get_block_ctrl<block_ctrl>(block_id_t("0/Block_1")); BOOST_CHECK_EQUAL(block1->get_block_id(), "0/Block_1"); } -BOOST_AUTO_TEST_CASE(test_device3_fail) { +BOOST_AUTO_TEST_CASE(test_device3_fail) +{ device3::sptr my_device = make_mock_device(); BOOST_CHECK(not my_device->has_block(block_id_t("0/FooBarBlock_0"))); @@ -184,13 +192,10 @@ BOOST_AUTO_TEST_CASE(test_device3_fail) { BOOST_CHECK(my_device->find_blocks<block_ctrl>("FooBarBlock").size() == 0); BOOST_REQUIRE_THROW( - my_device->get_block_ctrl(block_id_t("0/FooBarBlock_17")), - uhd::lookup_error - ); + my_device->get_block_ctrl(block_id_t("0/FooBarBlock_17")), uhd::lookup_error); BOOST_REQUIRE_THROW( my_device->get_block_ctrl<mock_block_ctrl>(block_id_t("0/Block_1")), - uhd::lookup_error - ); + uhd::lookup_error); } // vim: sw=4 et: diff --git a/host/tests/dict_test.cpp b/host/tests/dict_test.cpp index 53432d533..99fc2366c 100644 --- a/host/tests/dict_test.cpp +++ b/host/tests/dict_test.cpp @@ -5,15 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/types/dict.hpp> #include <boost/assign/list_of.hpp> +#include <boost/test/unit_test.hpp> -BOOST_AUTO_TEST_CASE(test_dict_init){ +BOOST_AUTO_TEST_CASE(test_dict_init) +{ uhd::dict<int, int> d; d[-1] = 3; - d[0] = 4; - d[1] = 5; + d[0] = 4; + d[1] = 5; BOOST_CHECK(d.has_key(0)); BOOST_CHECK(not d.has_key(2)); BOOST_CHECK(d.keys()[1] == 0); @@ -21,12 +22,9 @@ BOOST_AUTO_TEST_CASE(test_dict_init){ BOOST_CHECK_EQUAL(d[-1], 3); } -BOOST_AUTO_TEST_CASE(test_dict_assign){ - uhd::dict<int, int> d = boost::assign::map_list_of - (-1, 3) - (0, 4) - (1, 5) - ; +BOOST_AUTO_TEST_CASE(test_dict_assign) +{ + uhd::dict<int, int> d = boost::assign::map_list_of(-1, 3)(0, 4)(1, 5); BOOST_CHECK(d.has_key(0)); BOOST_CHECK(not d.has_key(2)); BOOST_CHECK(d.keys()[1] == 0); @@ -34,12 +32,9 @@ BOOST_AUTO_TEST_CASE(test_dict_assign){ BOOST_CHECK_EQUAL(d[-1], 3); } -BOOST_AUTO_TEST_CASE(test_const_dict){ - const uhd::dict<int, int> d = boost::assign::map_list_of - (-1, 3) - (0, 4) - (1, 5) - ; +BOOST_AUTO_TEST_CASE(test_const_dict) +{ + const uhd::dict<int, int> d = boost::assign::map_list_of(-1, 3)(0, 4)(1, 5); BOOST_CHECK(d.has_key(0)); BOOST_CHECK(not d.has_key(2)); BOOST_CHECK(d.keys()[1] == 0); @@ -48,12 +43,9 @@ BOOST_AUTO_TEST_CASE(test_const_dict){ BOOST_CHECK_THROW(d[2], std::exception); } -BOOST_AUTO_TEST_CASE(test_dict_pop){ - uhd::dict<int, int> d = boost::assign::map_list_of - (-1, 3) - (0, 4) - (1, 5) - ; +BOOST_AUTO_TEST_CASE(test_dict_pop) +{ + uhd::dict<int, int> d = boost::assign::map_list_of(-1, 3)(0, 4)(1, 5); BOOST_CHECK(d.has_key(0)); BOOST_CHECK_EQUAL(d.pop(0), 4); BOOST_CHECK(not d.has_key(0)); @@ -63,24 +55,18 @@ BOOST_AUTO_TEST_CASE(test_dict_pop){ BOOST_AUTO_TEST_CASE(test_dict_update) { - uhd::dict<std::string, std::string> d1 = boost::assign::map_list_of - ("key1", "val1") - ("key2", "val2") - ; - uhd::dict<std::string, std::string> d2 = boost::assign::map_list_of - ("key2", "val2x") - ("key3", "val3") - ; + uhd::dict<std::string, std::string> d1 = + boost::assign::map_list_of("key1", "val1")("key2", "val2"); + uhd::dict<std::string, std::string> d2 = + boost::assign::map_list_of("key2", "val2x")("key3", "val3"); d1.update(d2, false /* don't throw cause of conflict */); BOOST_CHECK_EQUAL(d1["key1"], "val1"); BOOST_CHECK_EQUAL(d1["key2"], "val2x"); BOOST_CHECK_EQUAL(d1["key3"], "val3"); - uhd::dict<std::string, std::string> d3 = boost::assign::map_list_of - ("key1", "val1") - ("key2", "val2") - ; + uhd::dict<std::string, std::string> d3 = + boost::assign::map_list_of("key1", "val1")("key2", "val2"); BOOST_CHECK_THROW(d3.update(d2), uhd::value_error); } @@ -121,6 +107,6 @@ BOOST_AUTO_TEST_CASE(test_dict_equals) BOOST_CHECK(d0 != d4); BOOST_CHECK(d0 != d5); // Redundant, but just to be sure - BOOST_CHECK(not (d0 == d2)); - BOOST_CHECK(not (d0 == d3)); + BOOST_CHECK(not(d0 == d2)); + BOOST_CHECK(not(d0 == d3)); } diff --git a/host/tests/dpdk_test.cpp b/host/tests/dpdk_test.cpp index 8a4e51af7..43ef3d388 100644 --- a/host/tests/dpdk_test.cpp +++ b/host/tests/dpdk_test.cpp @@ -8,18 +8,18 @@ */ -#include <cstdio> -#include <cstdbool> -#include <cstring> -#include <unistd.h> -#include <sys/time.h> -#include <errno.h> +#include "../transport/dpdk_zero_copy.hpp" #include <arpa/inet.h> +#include <errno.h> #include <sched.h> #include <sys/syscall.h> -#include "../transport/dpdk_zero_copy.hpp" +#include <sys/time.h> +#include <unistd.h> #include <boost/program_options.hpp> #include <boost/regex.hpp> +#include <cstdbool> +#include <cstdio> +#include <cstring> #include <iostream> static const boost::regex colons(":"); @@ -27,28 +27,30 @@ static const boost::regex colons(":"); namespace po = boost::program_options; namespace { - constexpr unsigned int NUM_MBUFS = 4095; /* Total number of mbufs in pool */ - constexpr unsigned int MBUF_CACHE_SIZE = 315; /* Size of cpu-local mbuf cache */ - constexpr unsigned int BURST_SIZE = 64; /* Maximum burst size for RX */ - - constexpr unsigned int NUM_PORTS = 2; /* Number of NIC ports */ - constexpr unsigned int TX_CREDITS = 28; /* Number of TX credits */ - constexpr unsigned int RX_CREDITS = 64; /* Number of RX credits */ - constexpr unsigned int BENCH_SPP = 700; /* "Samples" per packet */ -} +constexpr unsigned int NUM_MBUFS = 4095; /* Total number of mbufs in pool */ +constexpr unsigned int MBUF_CACHE_SIZE = 315; /* Size of cpu-local mbuf cache */ +constexpr unsigned int BURST_SIZE = 64; /* Maximum burst size for RX */ + +constexpr unsigned int NUM_PORTS = 2; /* Number of NIC ports */ +constexpr unsigned int TX_CREDITS = 28; /* Number of TX credits */ +constexpr unsigned int RX_CREDITS = 64; /* Number of RX credits */ +constexpr unsigned int BENCH_SPP = 700; /* "Samples" per packet */ +} // namespace -struct dpdk_test_args { +struct dpdk_test_args +{ unsigned int portid; std::string src_port; std::string dst_ip; std::string dst_port; - pthread_cond_t *cond; + pthread_cond_t* cond; pthread_mutex_t mutex; bool started; int cpu; }; -struct dpdk_test_stats { +struct dpdk_test_stats +{ uint32_t last_seqno; uint32_t dropped_packets; uint32_t lasts[16]; @@ -59,7 +61,7 @@ struct dpdk_test_stats { }; -static void process_udp(int id, uint32_t *udp_data, struct dpdk_test_stats *stats) +static void process_udp(int id, uint32_t* udp_data, struct dpdk_test_stats* stats) { if (udp_data[0] != stats[id].last_seqno + 1) { stats[id].lasts[stats[id].dropped_packets & 0xf] = stats[id].last_seqno; @@ -71,22 +73,24 @@ static void process_udp(int id, uint32_t *udp_data, struct dpdk_test_stats *stat stats[id].last_ackno = udp_data[1]; } -static void send_udp(uhd::transport::dpdk_zero_copy::sptr &stream, int id, - bool fc_only, struct dpdk_test_stats *stats) +static void send_udp(uhd::transport::dpdk_zero_copy::sptr& stream, + int id, + bool fc_only, + struct dpdk_test_stats* stats) { uhd::transport::managed_send_buffer::sptr mbuf = stream->get_send_buff(0); if (mbuf.get() == nullptr) { printf("Could not get TX buffer!\n"); return; } - auto *tx_data = mbuf->cast<uint32_t *>(); - tx_data[0] = fc_only ? stats[id].tx_seqno - 1 : stats[id].tx_seqno; - tx_data[1] = stats[id].last_seqno; + auto* tx_data = mbuf->cast<uint32_t*>(); + tx_data[0] = fc_only ? stats[id].tx_seqno - 1 : stats[id].tx_seqno; + tx_data[1] = stats[id].last_seqno; if (!fc_only) { - memset(&tx_data[2], stats[id].last_seqno, 8*BENCH_SPP); - stats[id].tx_xfer += 8*BENCH_SPP; + memset(&tx_data[2], stats[id].last_seqno, 8 * BENCH_SPP); + stats[id].tx_xfer += 8 * BENCH_SPP; } - size_t num_bytes = 8 + (fc_only ? 0 : 8*BENCH_SPP); + size_t num_bytes = 8 + (fc_only ? 0 : 8 * BENCH_SPP); mbuf->commit(num_bytes); mbuf.reset(); @@ -95,18 +99,20 @@ static void send_udp(uhd::transport::dpdk_zero_copy::sptr &stream, int id, } } -static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_ports, double timeout) +static void bench( + uhd::transport::dpdk_zero_copy::sptr* stream, uint32_t nb_ports, double timeout) { uint64_t total_xfer[NUM_PORTS]; uint32_t id; - struct dpdk_test_stats *stats = (struct dpdk_test_stats *) malloc(sizeof(*stats)*nb_ports); + struct dpdk_test_stats* stats = + (struct dpdk_test_stats*)malloc(sizeof(*stats) * nb_ports); for (id = 0; id < nb_ports; id++) { - stats[id].tx_seqno = 1; - stats[id].tx_xfer = 0; - stats[id].last_ackno = 0; - stats[id].last_seqno = 0; + stats[id].tx_seqno = 1; + stats[id].tx_xfer = 0; + stats[id].last_ackno = 0; + stats[id].last_seqno = 0; stats[id].dropped_packets = 0; - total_xfer[id] = 0; + total_xfer[id] = 0; } sleep(1); struct timeval bench_start, bench_end; @@ -115,8 +121,8 @@ static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_port * The test... */ uint64_t total_received = 0; - uint32_t consec_no_rx = 0; - while ((total_received / nb_ports) < 1000000 ) { //&& consec_no_rx < 10000) { + uint32_t consec_no_rx = 0; + while ((total_received / nb_ports) < 1000000) { //&& consec_no_rx < 10000) { for (id = 0; id < nb_ports; id++) { unsigned int nb_rx = 0; uhd::transport::managed_recv_buffer::sptr bufs[BURST_SIZE]; @@ -132,7 +138,9 @@ static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_port consec_no_rx++; if (consec_no_rx >= 100000) { uint32_t skt_drops = stream[id]->get_drop_count(); - //printf("TX seq %d, TX ack %d, RX seq %d, %d drops!\n", stats[id].tx_seqno, stats[id].last_ackno, stats[id].last_seqno, skt_drops); + // printf("TX seq %d, TX ack %d, RX seq %d, %d drops!\n", + // stats[id].tx_seqno, stats[id].last_ackno, stats[id].last_seqno, + // skt_drops); consec_no_rx = 0; break; } @@ -143,7 +151,7 @@ static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_port for (unsigned int buf = 0; buf < nb_rx; buf++) { total_xfer[id] += bufs[buf]->size(); - auto data = bufs[buf]->cast<uint32_t *>(); + auto data = bufs[buf]->cast<uint32_t*>(); process_udp(id, data, stats); } @@ -153,15 +161,17 @@ static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_port for (id = 0; id < nb_ports; id++) { /* TX portion */ uint32_t window_end = stats[id].last_ackno + TX_CREDITS; - //uint32_t window_end = last_seqno[port] + TX_CREDITS; + // uint32_t window_end = last_seqno[port] + TX_CREDITS; if (window_end <= stats[id].tx_seqno) { if (consec_no_rx == 9999) { send_udp(stream[id], id, true, stats); } - //send_udp(tx[id], id, true); + // send_udp(tx[id], id, true); ; } else { - for (unsigned int pktno = 0; (pktno < BURST_SIZE) && (stats[id].tx_seqno < window_end); pktno++) { + for (unsigned int pktno = 0; + (pktno < BURST_SIZE) && (stats[id].tx_seqno < window_end); + pktno++) { send_udp(stream[id], id, false, stats); } } @@ -174,13 +184,16 @@ static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_port printf("\n"); printf("Bytes received = %ld\n", total_xfer[id]); printf("Bytes sent = %ld\n", stats[id].tx_xfer); - printf("Time taken = %ld us\n", (bench_end.tv_sec - bench_start.tv_sec)*1000000 + (bench_end.tv_usec - bench_start.tv_usec)); - double elapsed_time = (bench_end.tv_sec - bench_start.tv_sec)*1000000 + (bench_end.tv_usec - bench_start.tv_usec); + printf("Time taken = %ld us\n", + (bench_end.tv_sec - bench_start.tv_sec) * 1000000 + + (bench_end.tv_usec - bench_start.tv_usec)); + double elapsed_time = (bench_end.tv_sec - bench_start.tv_sec) * 1000000 + + (bench_end.tv_usec - bench_start.tv_usec); elapsed_time *= 1.0e-6; double elapsed_bytes = total_xfer[id]; - printf("RX Performance = %e Gbps\n", elapsed_bytes*8.0/1.0e9/elapsed_time); + printf("RX Performance = %e Gbps\n", elapsed_bytes * 8.0 / 1.0e9 / elapsed_time); elapsed_bytes = stats[id].tx_xfer; - printf("TX Performance = %e Gbps\n", elapsed_bytes*8.0/1.0e9/elapsed_time); + printf("TX Performance = %e Gbps\n", elapsed_bytes * 8.0 / 1.0e9 / elapsed_time); uint32_t skt_drops = stream[id]->get_drop_count(); printf("Dropped %d packets\n", stats[id].dropped_packets); printf("Socket reports dropped %d packets\n", skt_drops); @@ -189,11 +202,10 @@ static void bench(uhd::transport::dpdk_zero_copy::sptr *stream, uint32_t nb_port break; printf("Last(%u), Recv(%u)\n", stats[id].lasts[i], stats[id].drops[i]); } - //printf("%d missed/dropped packets\n", errors); + // printf("%d missed/dropped packets\n", errors); printf("\n"); } free(stats); - } static inline void set_cpu(pthread_t t, int cpu) @@ -209,31 +221,29 @@ static inline void set_cpu(pthread_t t, int cpu) } } -void *prepare_and_bench_blocking(void *arg) +void* prepare_and_bench_blocking(void* arg) { - struct dpdk_test_args *args = (struct dpdk_test_args *) arg; + struct dpdk_test_args* args = (struct dpdk_test_args*)arg; pthread_mutex_lock(&args->mutex); pthread_t t = pthread_self(); set_cpu(t, args->cpu); args->started = true; pthread_cond_wait(args->cond, &args->mutex); - auto &ctx = uhd::transport::uhd_dpdk_ctx::get(); + auto& ctx = uhd::transport::uhd_dpdk_ctx::get(); uhd::transport::dpdk_zero_copy::sptr eth_data[1]; uhd::transport::zero_copy_xport_params buff_args; buff_args.recv_frame_size = 8000; buff_args.send_frame_size = 8000; buff_args.num_send_frames = 8; buff_args.num_recv_frames = 8; - auto dev_addr = uhd::device_addr_t(); - eth_data[0] = uhd::transport::dpdk_zero_copy::make( - ctx, + auto dev_addr = uhd::device_addr_t(); + eth_data[0] = uhd::transport::dpdk_zero_copy::make(ctx, args->portid, args->dst_ip, args->src_port, args->dst_port, buff_args, - dev_addr - ); + dev_addr); bench(eth_data, 1, 0.1); return 0; @@ -241,19 +251,19 @@ void *prepare_and_bench_blocking(void *arg) void prepare_and_bench_polling(void) { - auto &ctx = uhd::transport::uhd_dpdk_ctx::get(); + auto& ctx = uhd::transport::uhd_dpdk_ctx::get(); struct dpdk_test_args bench_args[2]; - bench_args[0].cond = NULL; - bench_args[0].started = true; - bench_args[0].portid = 0; + bench_args[0].cond = NULL; + bench_args[0].started = true; + bench_args[0].portid = 0; bench_args[0].src_port = "0xBEE7"; - bench_args[0].dst_ip = "192.168.0.4"; + bench_args[0].dst_ip = "192.168.0.4"; bench_args[0].dst_port = "0xBEE7"; - bench_args[1].cond = NULL; - bench_args[1].started = true; - bench_args[1].portid = 1; + bench_args[1].cond = NULL; + bench_args[1].started = true; + bench_args[1].portid = 1; bench_args[1].src_port = "0xBEE7"; - bench_args[1].dst_ip = "192.168.0.3"; + bench_args[1].dst_ip = "192.168.0.3"; bench_args[1].dst_port = "0xBEE7"; uhd::transport::dpdk_zero_copy::sptr eth_data[NUM_PORTS]; @@ -262,45 +272,43 @@ void prepare_and_bench_polling(void) buff_args.send_frame_size = 8000; buff_args.num_send_frames = 8; buff_args.num_recv_frames = 8; - auto dev_addr = uhd::device_addr_t(); + auto dev_addr = uhd::device_addr_t(); for (unsigned int i = 0; i < NUM_PORTS; i++) { - eth_data[i] = uhd::transport::dpdk_zero_copy::make( - ctx, + eth_data[i] = uhd::transport::dpdk_zero_copy::make(ctx, bench_args[i].portid, bench_args[i].dst_ip, bench_args[i].src_port, bench_args[i].dst_port, buff_args, - dev_addr - ); + dev_addr); } bench(eth_data, NUM_PORTS, 0.0); } -int main(int argc, char **argv) +int main(int argc, char** argv) { int retval, io0_cpu = 1, io1_cpu = 1, user0_cpu = 0, user1_cpu = 2; std::string args, cpusets; po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("args", po::value<std::string>(&args)->default_value(""), "UHD-DPDK args") - ("polling-mode", "Use polling mode (single thread on own core)") - ("cpusets", po::value<std::string>(&cpusets)->default_value(""), "which core(s) to use for a given thread (specify something like \"io0=1,io1=1,user0=0,user1=2\")") - ; + desc.add_options()("help", "help message")( + "args", po::value<std::string>(&args)->default_value(""), "UHD-DPDK args")( + "polling-mode", "Use polling mode (single thread on own core)")("cpusets", + po::value<std::string>(&cpusets)->default_value(""), + "which core(s) to use for a given thread (specify something like " + "\"io0=1,io1=1,user0=0,user1=2\")"); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("help")) { - std::cout << desc << std::endl; - return 0; + std::cout << desc << std::endl; + return 0; } auto dpdk_args = uhd::device_addr_t(args); - for (std::string &key : dpdk_args.keys()) { + for (std::string& key : dpdk_args.keys()) { /* device_addr_t splits on commas, so we use colons and replace */ if (key == "corelist" || key == "coremap") { dpdk_args[key] = boost::regex_replace(dpdk_args[key], colons, ","); @@ -308,7 +316,7 @@ int main(int argc, char **argv) } auto cpuset_map = uhd::device_addr_t(cpusets); - for (std::string &key : cpuset_map.keys()) { + for (std::string& key : cpuset_map.keys()) { if (key == "io0") { io0_cpu = std::stoi(cpuset_map[key], NULL, 0); } else if (key == "io1") { @@ -321,12 +329,12 @@ int main(int argc, char **argv) } int port_thread_mapping[2] = {io0_cpu, io1_cpu}; - auto &ctx = uhd::transport::uhd_dpdk_ctx::get(); + auto& ctx = uhd::transport::uhd_dpdk_ctx::get(); ctx.init(dpdk_args, 2, &port_thread_mapping[0], NUM_MBUFS, MBUF_CACHE_SIZE, 9000); - uint32_t eth_ip = htonl(0xc0a80003); + uint32_t eth_ip = htonl(0xc0a80003); uint32_t eth_mask = htonl(0xffffff00); - int status = ctx.set_ipv4_addr(0, eth_ip, eth_mask); + int status = ctx.set_ipv4_addr(0, eth_ip, eth_mask); if (status) { printf("Error while setting IP0: %d\n", status); return status; @@ -346,19 +354,19 @@ int main(int argc, char **argv) struct dpdk_test_args bench_args[2]; pthread_mutex_init(&bench_args[0].mutex, NULL); pthread_mutex_init(&bench_args[1].mutex, NULL); - bench_args[0].cpu = user0_cpu; - bench_args[0].cond = &cond; - bench_args[0].started = false; - bench_args[0].portid = 0; + bench_args[0].cpu = user0_cpu; + bench_args[0].cond = &cond; + bench_args[0].started = false; + bench_args[0].portid = 0; bench_args[0].src_port = "0xBEE7"; - bench_args[0].dst_ip = "192.168.0.4"; + bench_args[0].dst_ip = "192.168.0.4"; bench_args[0].dst_port = "0xBEE7"; - bench_args[1].cpu = user1_cpu; - bench_args[1].cond = &cond; - bench_args[1].started = false; - bench_args[1].portid = 1; + bench_args[1].cpu = user1_cpu; + bench_args[1].cond = &cond; + bench_args[1].started = false; + bench_args[1].portid = 1; bench_args[1].src_port = "0xBEE7"; - bench_args[1].dst_ip = "192.168.0.3"; + bench_args[1].dst_ip = "192.168.0.3"; bench_args[1].dst_port = "0xBEE7"; pthread_t threads[2]; @@ -366,29 +374,29 @@ int main(int argc, char **argv) pthread_create(&threads[1], NULL, prepare_and_bench_blocking, &bench_args[1]); do { - pthread_mutex_lock(&bench_args[0].mutex); - if (bench_args[0].started) - break; - pthread_mutex_unlock(&bench_args[0].mutex); + pthread_mutex_lock(&bench_args[0].mutex); + if (bench_args[0].started) + break; + pthread_mutex_unlock(&bench_args[0].mutex); } while (true); pthread_mutex_unlock(&bench_args[0].mutex); do { - pthread_mutex_lock(&bench_args[1].mutex); - if (bench_args[1].started) - break; - pthread_mutex_unlock(&bench_args[1].mutex); + pthread_mutex_lock(&bench_args[1].mutex); + if (bench_args[1].started) + break; + pthread_mutex_unlock(&bench_args[1].mutex); } while (true); pthread_mutex_unlock(&bench_args[1].mutex); pthread_cond_broadcast(&cond); - status = pthread_join(threads[0], (void **) &retval); + status = pthread_join(threads[0], (void**)&retval); if (status) { perror("Error while joining thread"); return status; } - status = pthread_join(threads[1], (void **) &retval); + status = pthread_join(threads[1], (void**)&retval); if (status) { perror("Error while joining thread"); return status; diff --git a/host/tests/eeprom_utils_test.cpp b/host/tests/eeprom_utils_test.cpp index 4407ad4e4..728b4b8b6 100644 --- a/host/tests/eeprom_utils_test.cpp +++ b/host/tests/eeprom_utils_test.cpp @@ -4,15 +4,19 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhdlib/utils/eeprom_utils.hpp> #include <boost/assign/list_of.hpp> +#include <boost/test/unit_test.hpp> using namespace boost::assign; -class upper_case_char { +class upper_case_char +{ public: - upper_case_char(char ch) {value = ch;} + upper_case_char(char ch) + { + value = ch; + } static upper_case_char from_string(std::string str) { return upper_case_char(toupper(str[0])); @@ -21,36 +25,28 @@ public: { return std::string(1, value); } + private: char value; }; BOOST_AUTO_TEST_CASE(test_eeprom_duplicate_check) { - const uhd::dict<std::string,std::string> curr_eeprom = map_list_of - ("0","A") - ("1","B") - ("2","C") - ; - const uhd::dict<std::string,std::string> new_eeprom_no_dups = map_list_of - ("0","d") - ("1","e") - ; - const uhd::dict<std::string,std::string> new_eeprom_dups_in_curr = map_list_of - ("0","b") - ; - const uhd::dict<std::string,std::string> new_eeprom_dups_in_new = map_list_of - ("0","c") - ("1","c") - ; - const uhd::dict<std::string,std::string> new_eeprom_dups_in_both = map_list_of - ("0","b") - ("1","B") - ; - const std::vector<std::string> keys = {"0","1","2"}; + const uhd::dict<std::string, std::string> curr_eeprom = + map_list_of("0", "A")("1", "B")("2", "C"); + const uhd::dict<std::string, std::string> new_eeprom_no_dups = + map_list_of("0", "d")("1", "e"); + const uhd::dict<std::string, std::string> new_eeprom_dups_in_curr = + map_list_of("0", "b"); + const uhd::dict<std::string, std::string> new_eeprom_dups_in_new = + map_list_of("0", "c")("1", "c"); + const uhd::dict<std::string, std::string> new_eeprom_dups_in_both = + map_list_of("0", "b")("1", "B"); + const std::vector<std::string> keys = {"0", "1", "2"}; BOOST_CHECK_EQUAL(check_for_duplicates<upper_case_char>( - "TEST", new_eeprom_no_dups, curr_eeprom, "Test Value", keys), false); + "TEST", new_eeprom_no_dups, curr_eeprom, "Test Value", keys), + false); BOOST_CHECK(check_for_duplicates<upper_case_char>( "TEST", new_eeprom_dups_in_curr, curr_eeprom, "Test Value", keys)); BOOST_CHECK(check_for_duplicates<upper_case_char>( diff --git a/host/tests/error_c_test.cpp b/host/tests/error_c_test.cpp index a60abe289..c697ebac7 100644 --- a/host/tests/error_c_test.cpp +++ b/host/tests/error_c_test.cpp @@ -7,11 +7,10 @@ #include <uhd/error.h> #include <uhd/types/dict.hpp> - -#include <boost/test/unit_test.hpp> #include <boost/algorithm/string.hpp> #include <boost/assign.hpp> #include <boost/format.hpp> +#include <boost/test/unit_test.hpp> /* * Test our conversions from exceptions to C-level UHD error codes. @@ -19,97 +18,93 @@ * to test our C++ macro, which returns the error code. */ -typedef struct { +typedef struct +{ std::string last_error; } dummy_handle_t; template <typename error_type> -UHD_INLINE uhd_error throw_uhd_exception(dummy_handle_t *handle, const uhd::exception* except){ - UHD_SAFE_C_SAVE_ERROR(handle, - throw *dynamic_cast<const error_type*>(except); - ) +UHD_INLINE uhd_error throw_uhd_exception( + dummy_handle_t* handle, const uhd::exception* except) +{ + UHD_SAFE_C_SAVE_ERROR(handle, throw *dynamic_cast<const error_type*>(except);) } -UHD_INLINE uhd_error throw_boost_exception(dummy_handle_t *handle){ - UHD_SAFE_C_SAVE_ERROR(handle, +UHD_INLINE uhd_error throw_boost_exception(dummy_handle_t* handle) +{ + UHD_SAFE_C_SAVE_ERROR( + handle, std::runtime_error except("This is a std::runtime_error, thrown by Boost."); - BOOST_THROW_EXCEPTION(except); - ) + BOOST_THROW_EXCEPTION(except);) } -UHD_INLINE uhd_error throw_std_exception(dummy_handle_t *handle){ - UHD_SAFE_C_SAVE_ERROR(handle, - throw std::runtime_error("This is a std::runtime_error."); - ) +UHD_INLINE uhd_error throw_std_exception(dummy_handle_t* handle) +{ + UHD_SAFE_C_SAVE_ERROR( + handle, throw std::runtime_error("This is a std::runtime_error.");) } -UHD_INLINE uhd_error throw_unknown_exception(dummy_handle_t *handle){ - UHD_SAFE_C_SAVE_ERROR(handle, - throw 1; - ) +UHD_INLINE uhd_error throw_unknown_exception(dummy_handle_t* handle) +{ + UHD_SAFE_C_SAVE_ERROR(handle, throw 1;) } // There are enough non-standard names that we can't just use a conversion function static const uhd::dict<std::string, std::string> pretty_exception_names = - boost::assign::map_list_of - ("assertion_error", "AssertionError") - ("lookup_error", "LookupError") - ("index_error", "LookupError: IndexError") - ("key_error", "LookupError: KeyError") - ("type_error", "TypeError") - ("value_error", "ValueError") - ("runtime_error", "RuntimeError") - ("not_implemented_error", "RuntimeError: NotImplementedError") - ("usb_error", "RuntimeError: USBError 1") - ("environment_error", "EnvironmentError") - ("io_error", "EnvironmentError: IOError") - ("os_error", "EnvironmentError: OSError") - ("system_error", "SystemError") - ; - -#define UHD_TEST_CHECK_ERROR_CODE(cpp_exception_type, c_error_code) \ - expected_msg = str(boost::format("This is a uhd::%s.") % BOOST_STRINGIZE(cpp_exception_type)); \ - uhd::cpp_exception_type cpp_exception_type ## _foo(expected_msg); \ - error_code = throw_uhd_exception<uhd::cpp_exception_type>(&handle, &cpp_exception_type ## _foo); \ - BOOST_CHECK_EQUAL(error_code, c_error_code); \ - expected_msg = str(boost::format("%s: %s") \ + boost::assign::map_list_of("assertion_error", "AssertionError")( + "lookup_error", "LookupError")("index_error", "LookupError: IndexError")( + "key_error", "LookupError: KeyError")("type_error", "TypeError")("value_error", + "ValueError")("runtime_error", "RuntimeError")("not_implemented_error", + "RuntimeError: NotImplementedError")("usb_error", "RuntimeError: USBError 1")( + "environment_error", "EnvironmentError")("io_error", "EnvironmentError: IOError")( + "os_error", "EnvironmentError: OSError")("system_error", "SystemError"); + +#define UHD_TEST_CHECK_ERROR_CODE(cpp_exception_type, c_error_code) \ + expected_msg = \ + str(boost::format("This is a uhd::%s.") % BOOST_STRINGIZE(cpp_exception_type)); \ + uhd::cpp_exception_type cpp_exception_type##_foo(expected_msg); \ + error_code = throw_uhd_exception<uhd::cpp_exception_type>( \ + &handle, &cpp_exception_type##_foo); \ + BOOST_CHECK_EQUAL(error_code, c_error_code); \ + expected_msg = str(boost::format("%s: %s") \ % pretty_exception_names.get(BOOST_STRINGIZE(cpp_exception_type)) \ - % expected_msg); \ - BOOST_CHECK_EQUAL(handle.last_error, expected_msg); \ + % expected_msg); \ + BOOST_CHECK_EQUAL(handle.last_error, expected_msg); \ BOOST_CHECK_EQUAL(get_c_global_error_string(), expected_msg); // uhd::usb_error has a different constructor -#define UHD_TEST_CHECK_USB_ERROR_CODE() \ - expected_msg = "This is a uhd::usb_error."; \ - uhd::usb_error usb_error_foo(1, expected_msg); \ - error_code = throw_uhd_exception<uhd::usb_error>(&handle, &usb_error_foo); \ - BOOST_CHECK_EQUAL(error_code, UHD_ERROR_USB); \ - expected_msg = str(boost::format("%s: %s") \ - % pretty_exception_names.get("usb_error") \ - % expected_msg); \ - BOOST_CHECK_EQUAL(handle.last_error, expected_msg); \ +#define UHD_TEST_CHECK_USB_ERROR_CODE() \ + expected_msg = "This is a uhd::usb_error."; \ + uhd::usb_error usb_error_foo(1, expected_msg); \ + error_code = throw_uhd_exception<uhd::usb_error>(&handle, &usb_error_foo); \ + BOOST_CHECK_EQUAL(error_code, UHD_ERROR_USB); \ + expected_msg = str(boost::format("%s: %s") % pretty_exception_names.get("usb_error") \ + % expected_msg); \ + BOOST_CHECK_EQUAL(handle.last_error, expected_msg); \ BOOST_CHECK_EQUAL(get_c_global_error_string(), expected_msg); -BOOST_AUTO_TEST_CASE(test_uhd_exception){ +BOOST_AUTO_TEST_CASE(test_uhd_exception) +{ dummy_handle_t handle; std::string expected_msg; uhd_error error_code; - UHD_TEST_CHECK_ERROR_CODE(assertion_error, UHD_ERROR_ASSERTION); - UHD_TEST_CHECK_ERROR_CODE(lookup_error, UHD_ERROR_LOOKUP); - UHD_TEST_CHECK_ERROR_CODE(index_error, UHD_ERROR_INDEX); - UHD_TEST_CHECK_ERROR_CODE(key_error, UHD_ERROR_KEY); - UHD_TEST_CHECK_ERROR_CODE(type_error, UHD_ERROR_TYPE); - UHD_TEST_CHECK_ERROR_CODE(value_error, UHD_ERROR_VALUE); - UHD_TEST_CHECK_ERROR_CODE(runtime_error, UHD_ERROR_RUNTIME); + UHD_TEST_CHECK_ERROR_CODE(assertion_error, UHD_ERROR_ASSERTION); + UHD_TEST_CHECK_ERROR_CODE(lookup_error, UHD_ERROR_LOOKUP); + UHD_TEST_CHECK_ERROR_CODE(index_error, UHD_ERROR_INDEX); + UHD_TEST_CHECK_ERROR_CODE(key_error, UHD_ERROR_KEY); + UHD_TEST_CHECK_ERROR_CODE(type_error, UHD_ERROR_TYPE); + UHD_TEST_CHECK_ERROR_CODE(value_error, UHD_ERROR_VALUE); + UHD_TEST_CHECK_ERROR_CODE(runtime_error, UHD_ERROR_RUNTIME); UHD_TEST_CHECK_ERROR_CODE(not_implemented_error, UHD_ERROR_NOT_IMPLEMENTED); - UHD_TEST_CHECK_ERROR_CODE(io_error, UHD_ERROR_IO); - UHD_TEST_CHECK_ERROR_CODE(os_error, UHD_ERROR_OS); - UHD_TEST_CHECK_ERROR_CODE(system_error, UHD_ERROR_SYSTEM); + UHD_TEST_CHECK_ERROR_CODE(io_error, UHD_ERROR_IO); + UHD_TEST_CHECK_ERROR_CODE(os_error, UHD_ERROR_OS); + UHD_TEST_CHECK_ERROR_CODE(system_error, UHD_ERROR_SYSTEM); UHD_TEST_CHECK_USB_ERROR_CODE(); } -BOOST_AUTO_TEST_CASE(test_boost_exception){ +BOOST_AUTO_TEST_CASE(test_boost_exception) +{ dummy_handle_t handle; uhd_error error_code = throw_boost_exception(&handle); @@ -117,7 +112,8 @@ BOOST_AUTO_TEST_CASE(test_boost_exception){ BOOST_CHECK_EQUAL(error_code, UHD_ERROR_BOOSTEXCEPT); } -BOOST_AUTO_TEST_CASE(test_std_exception){ +BOOST_AUTO_TEST_CASE(test_std_exception) +{ dummy_handle_t handle; uhd_error error_code = throw_std_exception(&handle); @@ -125,7 +121,8 @@ BOOST_AUTO_TEST_CASE(test_std_exception){ BOOST_CHECK_EQUAL(handle.last_error, "This is a std::runtime_error."); } -BOOST_AUTO_TEST_CASE(test_unknown_exception){ +BOOST_AUTO_TEST_CASE(test_unknown_exception) +{ dummy_handle_t handle; uhd_error error_code = throw_unknown_exception(&handle); diff --git a/host/tests/error_test.cpp b/host/tests/error_test.cpp index b749ca6f4..62411e06d 100644 --- a/host/tests/error_test.cpp +++ b/host/tests/error_test.cpp @@ -5,79 +5,76 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/exception.hpp> #include <uhd/utils/assert_has.hpp> -#include <vector> +#include <boost/test/unit_test.hpp> #include <iostream> +#include <vector> -BOOST_AUTO_TEST_CASE(test_exception_methods){ - try{ +BOOST_AUTO_TEST_CASE(test_exception_methods) +{ + try { throw uhd::assertion_error("your assertion failed: 1 != 2"); - } - catch(const uhd::exception &e){ + } catch (const uhd::exception& e) { std::cout << "what: " << e.what() << std::endl; std::cout << "code: " << e.code() << std::endl; } } -BOOST_AUTO_TEST_CASE(test_assert_has){ +BOOST_AUTO_TEST_CASE(test_assert_has) +{ std::vector<int> vec; vec.push_back(2); vec.push_back(3); vec.push_back(5); - //verify the uhd::has utility + // verify the uhd::has utility BOOST_CHECK(uhd::has(vec, 2)); BOOST_CHECK(not uhd::has(vec, 1)); std::cout << "The output of the assert_has error:" << std::endl; - try{ + try { uhd::assert_has(vec, 1, "prime"); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } -BOOST_AUTO_TEST_CASE(test_assert_throw){ +BOOST_AUTO_TEST_CASE(test_assert_throw) +{ std::cout << "The output of the assert throw error:" << std::endl; - try{ + try { UHD_ASSERT_THROW(2 + 2 == 5); - } - catch(const std::exception &e){ + } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } -BOOST_AUTO_TEST_CASE(test_exception_dynamic){ - uhd::exception *exception_clone; +BOOST_AUTO_TEST_CASE(test_exception_dynamic) +{ + uhd::exception* exception_clone; - //throw an exception and dynamically clone it - try{ + // throw an exception and dynamically clone it + try { throw uhd::runtime_error("noooooo"); - } - catch(const uhd::exception &e){ + } catch (const uhd::exception& e) { std::cout << e.what() << std::endl; exception_clone = e.dynamic_clone(); } - //now we dynamically re-throw the exception - try{ + // now we dynamically re-throw the exception + try { exception_clone->dynamic_throw(); - } - catch(const uhd::assertion_error &e){ + } catch (const uhd::assertion_error& e) { std::cout << e.what() << std::endl; BOOST_CHECK(false); - } - catch(const uhd::runtime_error &e){ + } catch (const uhd::runtime_error& e) { std::cout << e.what() << std::endl; BOOST_CHECK(true); - } - catch(const uhd::exception &e){ + } catch (const uhd::exception& e) { std::cout << e.what() << std::endl; BOOST_CHECK(false); } - delete exception_clone; //manual cleanup + delete exception_clone; // manual cleanup } diff --git a/host/tests/expert_test.cpp b/host/tests/expert_test.cpp index efd4f1d08..36a9ef03b 100644 --- a/host/tests/expert_test.cpp +++ b/host/tests/expert_test.cpp @@ -5,20 +5,21 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> -#include <boost/format.hpp> -#include <boost/make_shared.hpp> #include <uhd/property_tree.hpp> #include <uhdlib/experts/expert_container.hpp> #include <uhdlib/experts/expert_factory.hpp> +#include <boost/format.hpp> +#include <boost/make_shared.hpp> +#include <boost/test/unit_test.hpp> #include <fstream> using namespace uhd::experts; -class worker1_t : public worker_node_t { +class worker1_t : public worker_node_t +{ public: worker1_t(const node_retriever_t& db) - : worker_node_t("A+B=C"), _a(db, "A/desired"), _b(db, "B"), _c(db, "C") + : worker_node_t("A+B=C"), _a(db, "A/desired"), _b(db, "B"), _c(db, "C") { bind_accessor(_a); bind_accessor(_b); @@ -26,7 +27,8 @@ public: } private: - void resolve() { + void resolve() + { _c = _a + _b; } @@ -37,10 +39,11 @@ private: //============================================================================= -class worker2_t : public worker_node_t { +class worker2_t : public worker_node_t +{ public: worker2_t(const node_retriever_t& db) - : worker_node_t("C*D=E"), _c(db, "C"), _d(db, "D"), _e(db, "E") + : worker_node_t("C*D=E"), _c(db, "C"), _d(db, "D"), _e(db, "E") { bind_accessor(_c); bind_accessor(_d); @@ -48,7 +51,8 @@ public: } private: - void resolve() { + void resolve() + { _e.set(_c.get() * _d.get()); } @@ -59,17 +63,19 @@ private: //============================================================================= -class worker3_t : public worker_node_t { +class worker3_t : public worker_node_t +{ public: worker3_t(const node_retriever_t& db) - : worker_node_t("-B=F"), _b(db, "B"), _f(db, "F") + : worker_node_t("-B=F"), _b(db, "B"), _f(db, "F") { bind_accessor(_b); bind_accessor(_f); } private: - void resolve() { + void resolve() + { _f.set(-_b.get()); } @@ -79,10 +85,11 @@ private: //============================================================================= -class worker4_t : public worker_node_t { +class worker4_t : public worker_node_t +{ public: worker4_t(const node_retriever_t& db) - : worker_node_t("E-F=G"), _e(db, "E"), _f(db, "F"), _g(db, "G") + : worker_node_t("E-F=G"), _e(db, "E"), _f(db, "F"), _g(db, "G") { bind_accessor(_e); bind_accessor(_f); @@ -90,7 +97,8 @@ public: } private: - void resolve() { + void resolve() + { _g.set(_e.get() - _f.get()); } @@ -101,17 +109,19 @@ private: //============================================================================= -class worker5_t : public worker_node_t { +class worker5_t : public worker_node_t +{ public: worker5_t(const node_retriever_t& db, boost::shared_ptr<int> output) - : worker_node_t("Consume_G"), _g(db, "G"), _c(db, "C"), _output(output) + : worker_node_t("Consume_G"), _g(db, "G"), _c(db, "C"), _output(output) { bind_accessor(_g); -// bind_accessor(_c); + // bind_accessor(_c); } private: - void resolve() { + void resolve() + { *_output = _g; } @@ -121,82 +131,92 @@ private: boost::shared_ptr<int> _output; }; -class worker6_t : public worker_node_t { +class worker6_t : public worker_node_t +{ public: - worker6_t() : worker_node_t("null_worker") - { - } + worker6_t() : worker_node_t("null_worker") {} private: - void resolve() { - } + void resolve() {} }; //============================================================================= -#define DUMP_VARS \ - BOOST_TEST_MESSAGE( str(boost::format("### State = {A=%d%s, B=%d%s, C=%d%s, D=%d%s, E=%d%s, F=%d%s, G=%d%s}\n") % \ - nodeA.get() % (nodeA.is_dirty()?"*":"") % \ - nodeB.get() % (nodeB.is_dirty()?"*":"") % \ - nodeC.get() % (nodeC.is_dirty()?"*":"") % \ - nodeD.get() % (nodeD.is_dirty()?"*":"") % \ - nodeE.get() % (nodeE.is_dirty()?"*":"") % \ - nodeF.get() % (nodeF.is_dirty()?"*":"") % \ - nodeG.get() % (nodeG.is_dirty()?"*":"")) ); - -#define VALIDATE_ALL_DEPENDENCIES \ - BOOST_CHECK(!nodeA.is_dirty()); \ - BOOST_CHECK(!nodeB.is_dirty()); \ - BOOST_CHECK(!nodeC.is_dirty()); \ - BOOST_CHECK(!nodeD.is_dirty()); \ - BOOST_CHECK(!nodeE.is_dirty()); \ - BOOST_CHECK(!nodeF.is_dirty()); \ - BOOST_CHECK(!nodeG.is_dirty()); \ +#define DUMP_VARS \ + BOOST_TEST_MESSAGE(str( \ + boost::format( \ + "### State = {A=%d%s, B=%d%s, C=%d%s, D=%d%s, E=%d%s, F=%d%s, G=%d%s}\n") \ + % nodeA.get() % (nodeA.is_dirty() ? "*" : "") % nodeB.get() \ + % (nodeB.is_dirty() ? "*" : "") % nodeC.get() % (nodeC.is_dirty() ? "*" : "") \ + % nodeD.get() % (nodeD.is_dirty() ? "*" : "") % nodeE.get() \ + % (nodeE.is_dirty() ? "*" : "") % nodeF.get() % (nodeF.is_dirty() ? "*" : "") \ + % nodeG.get() % (nodeG.is_dirty() ? "*" : ""))); + +#define VALIDATE_ALL_DEPENDENCIES \ + BOOST_CHECK(!nodeA.is_dirty()); \ + BOOST_CHECK(!nodeB.is_dirty()); \ + BOOST_CHECK(!nodeC.is_dirty()); \ + BOOST_CHECK(!nodeD.is_dirty()); \ + BOOST_CHECK(!nodeE.is_dirty()); \ + BOOST_CHECK(!nodeF.is_dirty()); \ + BOOST_CHECK(!nodeG.is_dirty()); \ BOOST_CHECK(nodeC.get() == nodeA.get() + nodeB.get()); \ BOOST_CHECK(nodeE.get() == nodeC.get() * nodeD.get()); \ - BOOST_CHECK(nodeF.get() == - nodeB.get()); \ + BOOST_CHECK(nodeF.get() == -nodeB.get()); \ BOOST_CHECK(nodeG.get() == nodeE.get() - nodeF.get()); \ BOOST_CHECK(nodeG.get() == *final_output); -BOOST_AUTO_TEST_CASE(test_experts){ - //Initialize container object +BOOST_AUTO_TEST_CASE(test_experts) +{ + // Initialize container object expert_container::sptr container = expert_factory::create_container("example"); - uhd::property_tree::sptr tree = uhd::property_tree::make(); + uhd::property_tree::sptr tree = uhd::property_tree::make(); - //Output of expert tree + // Output of expert tree boost::shared_ptr<int> final_output = boost::make_shared<int>(); - //Add data nodes to container - expert_factory::add_dual_prop_node<int>(container, tree, "A", 0, uhd::experts::AUTO_RESOLVE_ON_WRITE); + // Add data nodes to container + expert_factory::add_dual_prop_node<int>( + container, tree, "A", 0, uhd::experts::AUTO_RESOLVE_ON_WRITE); expert_factory::add_prop_node<int>(container, tree, "B", 0); expert_factory::add_data_node<int>(container, "C", 0); expert_factory::add_data_node<int>(container, "D", 1); - expert_factory::add_prop_node<int>(container, tree, "E", 0, uhd::experts::AUTO_RESOLVE_ON_READ); + expert_factory::add_prop_node<int>( + container, tree, "E", 0, uhd::experts::AUTO_RESOLVE_ON_READ); expert_factory::add_data_node<int>(container, "F", 0); expert_factory::add_data_node<int>(container, "G", 0); - //Add worker nodes to container + // Add worker nodes to container expert_factory::add_worker_node<worker1_t>(container, container->node_retriever()); expert_factory::add_worker_node<worker2_t>(container, container->node_retriever()); expert_factory::add_worker_node<worker3_t>(container, container->node_retriever()); expert_factory::add_worker_node<worker4_t>(container, container->node_retriever()); - expert_factory::add_worker_node<worker5_t>(container, container->node_retriever(), final_output); + expert_factory::add_worker_node<worker5_t>( + container, container->node_retriever(), final_output); expert_factory::add_worker_node<worker6_t>(container); - //Once initialized, getting modify access to graph nodes is possible (by design) but extremely red-flaggy! - //But we do it here to monitor things - data_node_t<int>& nodeA = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("A/desired")))); - data_node_t<int>& nodeB = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("B")))); - data_node_t<int>& nodeC = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("C")))); - data_node_t<int>& nodeD = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("D")))); - data_node_t<int>& nodeE = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("E")))); - data_node_t<int>& nodeF = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("F")))); - data_node_t<int>& nodeG = *(const_cast< data_node_t<int>* >(dynamic_cast< const data_node_t<int>* >(&container->node_retriever().lookup("G")))); + // Once initialized, getting modify access to graph nodes is possible (by design) but + // extremely red-flaggy! But we do it here to monitor things + data_node_t<int>& nodeA = + *(const_cast<data_node_t<int>*>(dynamic_cast<const data_node_t<int>*>( + &container->node_retriever().lookup("A/desired")))); + data_node_t<int>& nodeB = *(const_cast<data_node_t<int>*>( + dynamic_cast<const data_node_t<int>*>(&container->node_retriever().lookup("B")))); + data_node_t<int>& nodeC = *(const_cast<data_node_t<int>*>( + dynamic_cast<const data_node_t<int>*>(&container->node_retriever().lookup("C")))); + data_node_t<int>& nodeD = *(const_cast<data_node_t<int>*>( + dynamic_cast<const data_node_t<int>*>(&container->node_retriever().lookup("D")))); + data_node_t<int>& nodeE = *(const_cast<data_node_t<int>*>( + dynamic_cast<const data_node_t<int>*>(&container->node_retriever().lookup("E")))); + data_node_t<int>& nodeF = *(const_cast<data_node_t<int>*>( + dynamic_cast<const data_node_t<int>*>(&container->node_retriever().lookup("F")))); + data_node_t<int>& nodeG = *(const_cast<data_node_t<int>*>( + dynamic_cast<const data_node_t<int>*>(&container->node_retriever().lookup("G")))); DUMP_VARS - //Ensure init behavior + // Ensure init behavior BOOST_CHECK(nodeA.is_dirty()); BOOST_CHECK(nodeB.is_dirty()); BOOST_CHECK(nodeC.is_dirty()); @@ -205,18 +225,19 @@ BOOST_AUTO_TEST_CASE(test_experts){ BOOST_CHECK(nodeF.is_dirty()); BOOST_CHECK(nodeG.is_dirty()); container->resolve_all(); - VALIDATE_ALL_DEPENDENCIES //Ensure a default resolve + VALIDATE_ALL_DEPENDENCIES // Ensure a default resolve - //Ensure basic node value propagation - tree->access<int>("B").set(3); - BOOST_CHECK(nodeB.get() == 3); //Ensure value propagated - BOOST_CHECK(nodeB.is_dirty()); //Ensure that nothing got resolved... + // Ensure basic node value propagation + tree->access<int>("B") + .set(3); + BOOST_CHECK(nodeB.get() == 3); // Ensure value propagated + BOOST_CHECK(nodeB.is_dirty()); // Ensure that nothing got resolved... container->resolve_all(); VALIDATE_ALL_DEPENDENCIES - nodeD.set(2); //Hack for testing + nodeD.set(2); // Hack for testing - //Ensure auto-resolve on write + // Ensure auto-resolve on write tree->access<int>("A").set(200); BOOST_CHECK(nodeC.get() == nodeA.get() + nodeB.get()); BOOST_CHECK(nodeE.get() == nodeC.get() * nodeD.get()); @@ -227,7 +248,7 @@ BOOST_AUTO_TEST_CASE(test_experts){ container->resolve_all(); VALIDATE_ALL_DEPENDENCIES - //Ensure auto-resolve on read + // Ensure auto-resolve on read tree->access<int>("E").get(); BOOST_CHECK(nodeC.get() == nodeA.get() + nodeB.get()); BOOST_CHECK(nodeE.get() == nodeC.get() * nodeD.get()); @@ -236,7 +257,7 @@ BOOST_AUTO_TEST_CASE(test_experts){ container->resolve_all(true); VALIDATE_ALL_DEPENDENCIES - //Resolve to/from + // Resolve to/from tree->access<int>("A").set(-1); container->resolve_to("C"); BOOST_CHECK(nodeC.get() == nodeA.get() + nodeB.get()); diff --git a/host/tests/fe_conn_test.cpp b/host/tests/fe_conn_test.cpp index 34ebb7b33..bbf79835f 100644 --- a/host/tests/fe_conn_test.cpp +++ b/host/tests/fe_conn_test.cpp @@ -5,19 +5,20 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/usrp/fe_connection.hpp> #include <uhd/exception.hpp> +#include <uhd/usrp/fe_connection.hpp> #include <boost/test/unit_test.hpp> using namespace uhd::usrp; -BOOST_AUTO_TEST_CASE(test_quardrature){ +BOOST_AUTO_TEST_CASE(test_quardrature) +{ fe_connection_t IQ("IQ"), QI("QI"), IbQ("IbQ"), QbI("QbI"), QbIb("QbIb"); - BOOST_CHECK(IQ.get_sampling_mode()==fe_connection_t::QUADRATURE); - BOOST_CHECK(QI.get_sampling_mode()==fe_connection_t::QUADRATURE); - BOOST_CHECK(IbQ.get_sampling_mode()==fe_connection_t::QUADRATURE); - BOOST_CHECK(QbI.get_sampling_mode()==fe_connection_t::QUADRATURE); - BOOST_CHECK(QbIb.get_sampling_mode()==fe_connection_t::QUADRATURE); + BOOST_CHECK(IQ.get_sampling_mode() == fe_connection_t::QUADRATURE); + BOOST_CHECK(QI.get_sampling_mode() == fe_connection_t::QUADRATURE); + BOOST_CHECK(IbQ.get_sampling_mode() == fe_connection_t::QUADRATURE); + BOOST_CHECK(QbI.get_sampling_mode() == fe_connection_t::QUADRATURE); + BOOST_CHECK(QbIb.get_sampling_mode() == fe_connection_t::QUADRATURE); BOOST_CHECK(not IQ.is_iq_swapped()); BOOST_CHECK(QI.is_iq_swapped()); @@ -38,12 +39,13 @@ BOOST_AUTO_TEST_CASE(test_quardrature){ BOOST_CHECK(QbIb.is_q_inverted()); } -BOOST_AUTO_TEST_CASE(test_heterodyne){ +BOOST_AUTO_TEST_CASE(test_heterodyne) +{ fe_connection_t II("II"), QQ("QQ"), IbIb("IbIb"), QbQb("QbQb"); - BOOST_CHECK(II.get_sampling_mode()==fe_connection_t::HETERODYNE); - BOOST_CHECK(QQ.get_sampling_mode()==fe_connection_t::HETERODYNE); - BOOST_CHECK(IbIb.get_sampling_mode()==fe_connection_t::HETERODYNE); - BOOST_CHECK(QbQb.get_sampling_mode()==fe_connection_t::HETERODYNE); + BOOST_CHECK(II.get_sampling_mode() == fe_connection_t::HETERODYNE); + BOOST_CHECK(QQ.get_sampling_mode() == fe_connection_t::HETERODYNE); + BOOST_CHECK(IbIb.get_sampling_mode() == fe_connection_t::HETERODYNE); + BOOST_CHECK(QbQb.get_sampling_mode() == fe_connection_t::HETERODYNE); BOOST_CHECK(not II.is_iq_swapped()); BOOST_CHECK(QQ.is_iq_swapped()); @@ -66,12 +68,13 @@ BOOST_AUTO_TEST_CASE(test_heterodyne){ BOOST_CHECK_THROW(fe_connection_t dummy("QbQ"), uhd::value_error); } -BOOST_AUTO_TEST_CASE(test_real){ +BOOST_AUTO_TEST_CASE(test_real) +{ fe_connection_t I("I"), Q("Q"), Ib("Ib"), Qb("Qb"); - BOOST_CHECK(I.get_sampling_mode()==fe_connection_t::REAL); - BOOST_CHECK(Q.get_sampling_mode()==fe_connection_t::REAL); - BOOST_CHECK(Ib.get_sampling_mode()==fe_connection_t::REAL); - BOOST_CHECK(Qb.get_sampling_mode()==fe_connection_t::REAL); + BOOST_CHECK(I.get_sampling_mode() == fe_connection_t::REAL); + BOOST_CHECK(Q.get_sampling_mode() == fe_connection_t::REAL); + BOOST_CHECK(Ib.get_sampling_mode() == fe_connection_t::REAL); + BOOST_CHECK(Qb.get_sampling_mode() == fe_connection_t::REAL); BOOST_CHECK(not I.is_iq_swapped()); BOOST_CHECK(Q.is_iq_swapped()); @@ -89,7 +92,8 @@ BOOST_AUTO_TEST_CASE(test_real){ BOOST_CHECK(not Qb.is_q_inverted()); } -BOOST_AUTO_TEST_CASE(test_invalid){ +BOOST_AUTO_TEST_CASE(test_invalid) +{ BOOST_CHECK_THROW(fe_connection_t dummy("blah"), uhd::value_error); BOOST_CHECK_THROW(fe_connection_t dummy("123456"), uhd::value_error); BOOST_CHECK_THROW(fe_connection_t dummy("ii"), uhd::value_error); diff --git a/host/tests/fp_compare_delta_test.cpp b/host/tests/fp_compare_delta_test.cpp index 5023d660a..ae1f14281 100644 --- a/host/tests/fp_compare_delta_test.cpp +++ b/host/tests/fp_compare_delta_test.cpp @@ -10,20 +10,21 @@ using namespace uhd::math::fp_compare; -BOOST_AUTO_TEST_CASE(fp_compare_delta_constructors) { +BOOST_AUTO_TEST_CASE(fp_compare_delta_constructors) +{ // Test default constructor fp_compare_delta<float> alpha = fp_compare_delta<float>(7457392.0); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); BOOST_CHECK_EQUAL(alpha._value, beta._value); BOOST_CHECK_EQUAL(alpha._delta, beta._delta); // Test constructor with specified delta - fp_compare_delta<float> foxtrot = fp_compare_delta<float>(alpha._value, - uhd::math::SINGLE_PRECISION_DELTA); - fp_compare_delta<float> gamma = fp_compare_delta<float>(alpha._value, - 2 * uhd::math::SINGLE_PRECISION_DELTA); + fp_compare_delta<float> foxtrot = + fp_compare_delta<float>(alpha._value, uhd::math::SINGLE_PRECISION_DELTA); + fp_compare_delta<float> gamma = + fp_compare_delta<float>(alpha._value, 2 * uhd::math::SINGLE_PRECISION_DELTA); BOOST_CHECK_EQUAL(alpha._delta, foxtrot._delta); - BOOST_CHECK(not (alpha._delta == gamma._delta)); + BOOST_CHECK(not(alpha._delta == gamma._delta)); // Test copy-constructor fp_compare_delta<float> charlie = fp_compare_delta<float>(alpha); @@ -36,19 +37,20 @@ BOOST_AUTO_TEST_CASE(fp_compare_delta_constructors) { BOOST_CHECK_EQUAL(alpha._delta, delta._delta); } -BOOST_AUTO_TEST_CASE(double_compare_constructors) { +BOOST_AUTO_TEST_CASE(double_compare_constructors) +{ // Test default constructor fp_compare_delta<double> alpha = fp_compare_delta<double>(45739210286.0101); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); BOOST_CHECK_EQUAL(alpha._value, beta._value); BOOST_CHECK_EQUAL(alpha._delta, beta._delta); // Test constructor with specified delta - fp_compare_delta<double> foxtrot = fp_compare_delta<double>(alpha._value, - uhd::math::DOUBLE_PRECISION_DELTA); + fp_compare_delta<double> foxtrot = + fp_compare_delta<double>(alpha._value, uhd::math::DOUBLE_PRECISION_DELTA); fp_compare_delta<double> gamma = fp_compare_delta<double>(alpha._value, 2.0e-6); BOOST_CHECK_EQUAL(alpha._delta, foxtrot._delta); - BOOST_CHECK(not (alpha._delta == gamma._delta)); + BOOST_CHECK(not(alpha._delta == gamma._delta)); // Test copy-constructor fp_compare_delta<double> charlie = fp_compare_delta<double>(alpha); @@ -61,56 +63,61 @@ BOOST_AUTO_TEST_CASE(double_compare_constructors) { BOOST_CHECK_EQUAL(alpha._delta, delta._delta); } -BOOST_AUTO_TEST_CASE(float_equality_operators) { +BOOST_AUTO_TEST_CASE(float_equality_operators) +{ // Test basic equality operator fp_compare_delta<float> alpha = fp_compare_delta<float>(1.0); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); BOOST_CHECK(alpha == beta); BOOST_CHECK(alpha == float(alpha._value)); // Test equality edge case at difference = delta - fp_compare_delta<float> charlie = fp_compare_delta<float>(alpha._value - + uhd::math::SINGLE_PRECISION_DELTA); - BOOST_CHECK(not (alpha == charlie)); - BOOST_CHECK(not (alpha == float(alpha._value + uhd::math::SINGLE_PRECISION_DELTA))); + fp_compare_delta<float> charlie = + fp_compare_delta<float>(alpha._value + uhd::math::SINGLE_PRECISION_DELTA); + BOOST_CHECK(not(alpha == charlie)); + BOOST_CHECK(not(alpha == float(alpha._value + uhd::math::SINGLE_PRECISION_DELTA))); } -BOOST_AUTO_TEST_CASE(double_equality_operators) { +BOOST_AUTO_TEST_CASE(double_equality_operators) +{ // Test basic equality operator fp_compare_delta<double> alpha = fp_compare_delta<double>(1.0); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); BOOST_CHECK(alpha == beta); BOOST_CHECK(alpha == double(beta._value)); // Test equality edge case at delta = delta - fp_compare_delta<double> charlie = fp_compare_delta<double>(alpha._value - + uhd::math::DOUBLE_PRECISION_DELTA); - BOOST_CHECK(not (alpha == charlie)); - BOOST_CHECK(not (alpha == double(alpha._value + uhd::math::DOUBLE_PRECISION_DELTA))); + fp_compare_delta<double> charlie = + fp_compare_delta<double>(alpha._value + uhd::math::DOUBLE_PRECISION_DELTA); + BOOST_CHECK(not(alpha == charlie)); + BOOST_CHECK(not(alpha == double(alpha._value + uhd::math::DOUBLE_PRECISION_DELTA))); } -BOOST_AUTO_TEST_CASE(float_inequality_operators) { +BOOST_AUTO_TEST_CASE(float_inequality_operators) +{ // Test inequality operator, which is based on equality operator fp_compare_delta<float> alpha = fp_compare_delta<float>(127.0f); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value + 1.19e-3f); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value + 1.19e-3f); BOOST_CHECK(alpha != beta); BOOST_CHECK(alpha != float(alpha._value + 1.19e-3)); } -BOOST_AUTO_TEST_CASE(double_inequality_operators) { +BOOST_AUTO_TEST_CASE(double_inequality_operators) +{ // Test inequality operator, which is based on equality operator fp_compare_delta<double> alpha = fp_compare_delta<double>(1.0); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value + 1.19e-5); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value + 1.19e-5); BOOST_CHECK(alpha != beta); BOOST_CHECK(alpha != double(alpha._value + 1.19e-5)); } -BOOST_AUTO_TEST_CASE(float_lessthan_operators) { +BOOST_AUTO_TEST_CASE(float_lessthan_operators) +{ // Test less-than operator fp_compare_delta<float> alpha = fp_compare_delta<float>(274192.7f); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value - 0.2f); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value - 0.2f); BOOST_CHECK(beta < alpha); BOOST_CHECK(float(alpha._value - 0.2) < alpha); @@ -118,14 +125,15 @@ BOOST_AUTO_TEST_CASE(float_lessthan_operators) { // Confirm false less-than case fp_compare_delta<float> charlie = fp_compare_delta<float>(alpha._value - 1.2f); - BOOST_CHECK(not (alpha < charlie)); - BOOST_CHECK(not (alpha < float(alpha._value - 1.2f))); + BOOST_CHECK(not(alpha < charlie)); + BOOST_CHECK(not(alpha < float(alpha._value - 1.2f))); } -BOOST_AUTO_TEST_CASE(double_lessthan_operators) { +BOOST_AUTO_TEST_CASE(double_lessthan_operators) +{ // Test less-than operator fp_compare_delta<double> alpha = fp_compare_delta<double>(274192856.762312); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value - 0.0002); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value - 0.0002); BOOST_CHECK(beta < alpha); BOOST_CHECK(double(alpha._value - 0.0002) < alpha); @@ -133,14 +141,15 @@ BOOST_AUTO_TEST_CASE(double_lessthan_operators) { // Confirm false less-than case fp_compare_delta<double> charlie = fp_compare_delta<double>(alpha._value - 1.0012); - BOOST_CHECK(not (alpha < charlie)); - BOOST_CHECK(not (alpha < double(alpha._value - 1.0012))); + BOOST_CHECK(not(alpha < charlie)); + BOOST_CHECK(not(alpha < double(alpha._value - 1.0012))); } -BOOST_AUTO_TEST_CASE(float_lessthanequals_operators) { +BOOST_AUTO_TEST_CASE(float_lessthanequals_operators) +{ // Test that <= correctly reports for equal values fp_compare_delta<float> alpha = fp_compare_delta<float>(827.3f); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); BOOST_CHECK(alpha <= beta); BOOST_CHECK(alpha <= float(alpha._value)); @@ -152,10 +161,11 @@ BOOST_AUTO_TEST_CASE(float_lessthanequals_operators) { BOOST_CHECK(float(alpha._value - 1.2) <= alpha); } -BOOST_AUTO_TEST_CASE(double_lessthanequals_operators) { +BOOST_AUTO_TEST_CASE(double_lessthanequals_operators) +{ // Test that <= correctly reports for equal values fp_compare_delta<double> alpha = fp_compare_delta<double>(837652123.383764); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); BOOST_CHECK(alpha <= beta); BOOST_CHECK(alpha <= double(alpha._value)); @@ -167,10 +177,11 @@ BOOST_AUTO_TEST_CASE(double_lessthanequals_operators) { BOOST_CHECK(double(alpha._value - 0.0012) <= alpha); } -BOOST_AUTO_TEST_CASE(float_greaterthan_operators) { +BOOST_AUTO_TEST_CASE(float_greaterthan_operators) +{ // Test basic greater-than functionality fp_compare_delta<float> alpha = fp_compare_delta<float>(98325.4f); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value + 0.15f); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value + 0.15f); BOOST_CHECK(beta > alpha); BOOST_CHECK(float(alpha._value + 0.15) > alpha); @@ -178,14 +189,15 @@ BOOST_AUTO_TEST_CASE(float_greaterthan_operators) { // Test false greater-than case fp_compare_delta<float> charlie = fp_compare_delta<float>(alpha._value + 1.2f); - BOOST_CHECK(not (alpha > charlie)); - BOOST_CHECK(not (alpha > float(alpha._value + 1.2))); + BOOST_CHECK(not(alpha > charlie)); + BOOST_CHECK(not(alpha > float(alpha._value + 1.2))); } -BOOST_AUTO_TEST_CASE(double_greaterthan_operators) { +BOOST_AUTO_TEST_CASE(double_greaterthan_operators) +{ // Test basic greater-than functionality fp_compare_delta<double> alpha = fp_compare_delta<double>(643907213.428475); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value + 0.0002); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value + 0.0002); BOOST_CHECK(beta > alpha); BOOST_CHECK(double(alpha._value + 0.0002) > alpha); @@ -193,14 +205,15 @@ BOOST_AUTO_TEST_CASE(double_greaterthan_operators) { // Test false greater-than case fp_compare_delta<double> charlie = fp_compare_delta<double>(alpha._value + 0.0012); - BOOST_CHECK(not (alpha > charlie)); - BOOST_CHECK(not (alpha > double(alpha._value + 0.0012))); + BOOST_CHECK(not(alpha > charlie)); + BOOST_CHECK(not(alpha > double(alpha._value + 0.0012))); } -BOOST_AUTO_TEST_CASE(float_greaterthanequals_operators) { +BOOST_AUTO_TEST_CASE(float_greaterthanequals_operators) +{ // Test that >= correctly reports for equal values fp_compare_delta<float> alpha = fp_compare_delta<float>(7834.89f); - fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); + fp_compare_delta<float> beta = fp_compare_delta<float>(alpha._value); BOOST_CHECK(alpha >= beta); BOOST_CHECK(alpha >= float(alpha._value)); @@ -212,10 +225,11 @@ BOOST_AUTO_TEST_CASE(float_greaterthanequals_operators) { BOOST_CHECK(float(alpha._value + 4.8) >= alpha); } -BOOST_AUTO_TEST_CASE(double_greaterthanequals_operators) { +BOOST_AUTO_TEST_CASE(double_greaterthanequals_operators) +{ // Test that >= correctly reports for equal values fp_compare_delta<double> alpha = fp_compare_delta<double>(737623834.89843); - fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); + fp_compare_delta<double> beta = fp_compare_delta<double>(alpha._value); BOOST_CHECK(alpha >= beta); BOOST_CHECK(alpha >= double(alpha._value)); @@ -227,16 +241,20 @@ BOOST_AUTO_TEST_CASE(double_greaterthanequals_operators) { BOOST_CHECK(double(alpha._value + 3.0008) >= alpha); } -BOOST_AUTO_TEST_CASE(fp_compare_large_delta) { - BOOST_CHECK(fp_compare_delta<double>(61440000.047870710492, 0.1) == 61440000.000000000000); - BOOST_CHECK(fp_compare_delta<double>(61440000.047870710492, 0.1) <= 61440000.000000000000); - BOOST_CHECK(fp_compare_delta<double>(61440000.047870710492, 0.1) >= 61440000.000000000000); +BOOST_AUTO_TEST_CASE(fp_compare_large_delta) +{ + BOOST_CHECK( + fp_compare_delta<double>(61440000.047870710492, 0.1) == 61440000.000000000000); + BOOST_CHECK( + fp_compare_delta<double>(61440000.047870710492, 0.1) <= 61440000.000000000000); + BOOST_CHECK( + fp_compare_delta<double>(61440000.047870710492, 0.1) >= 61440000.000000000000); BOOST_CHECK(fp_compare_delta<double>(1.0, 10.0) == 2.0); } -BOOST_AUTO_TEST_CASE(frequency_compare_function) { - +BOOST_AUTO_TEST_CASE(frequency_compare_function) +{ BOOST_CHECK(uhd::math::frequencies_are_equal(6817333232.0, 6817333232.0)); BOOST_CHECK(!uhd::math::frequencies_are_equal(6817333233.0, 6817333232.0)); BOOST_CHECK(uhd::math::frequencies_are_equal(6817333232.1, 6817333232.1)); diff --git a/host/tests/fp_compare_epsilon_test.cpp b/host/tests/fp_compare_epsilon_test.cpp index 5e5971586..0c2a7f1cb 100644 --- a/host/tests/fp_compare_epsilon_test.cpp +++ b/host/tests/fp_compare_epsilon_test.cpp @@ -10,19 +10,20 @@ using namespace uhd::math::fp_compare; -BOOST_AUTO_TEST_CASE(fp_compare_epsilon_constructors) { +BOOST_AUTO_TEST_CASE(fp_compare_epsilon_constructors) +{ // Test default constructor fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(7457392.0); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); BOOST_CHECK_EQUAL(alpha._value, beta._value); BOOST_CHECK_EQUAL(alpha._epsilon, beta._epsilon); // Test constructor with specified epsilon - fp_compare_epsilon<float> foxtrot = fp_compare_epsilon<float>(alpha._value, - uhd::math::SINGLE_PRECISION_EPSILON); + fp_compare_epsilon<float> foxtrot = + fp_compare_epsilon<float>(alpha._value, uhd::math::SINGLE_PRECISION_EPSILON); fp_compare_epsilon<float> gamma = fp_compare_epsilon<float>(alpha._value, 2.0e-1f); BOOST_CHECK_EQUAL(alpha._epsilon, foxtrot._epsilon); - BOOST_CHECK(not (alpha._epsilon == gamma._epsilon)); + BOOST_CHECK(not(alpha._epsilon == gamma._epsilon)); // Test copy-constructor fp_compare_epsilon<float> charlie = fp_compare_epsilon<float>(alpha); @@ -35,19 +36,20 @@ BOOST_AUTO_TEST_CASE(fp_compare_epsilon_constructors) { BOOST_CHECK_EQUAL(alpha._epsilon, delta._epsilon); } -BOOST_AUTO_TEST_CASE(double_compare_constructors) { +BOOST_AUTO_TEST_CASE(double_compare_constructors) +{ // Test default constructor fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(45739210286.0101); - fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); + fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); BOOST_CHECK_EQUAL(alpha._value, beta._value); BOOST_CHECK_EQUAL(alpha._epsilon, beta._epsilon); // Test constructor with specified epsilon - fp_compare_epsilon<double> foxtrot = fp_compare_epsilon<double>(alpha._value, - uhd::math::DOUBLE_PRECISION_EPSILON); + fp_compare_epsilon<double> foxtrot = + fp_compare_epsilon<double>(alpha._value, uhd::math::DOUBLE_PRECISION_EPSILON); fp_compare_epsilon<double> gamma = fp_compare_epsilon<double>(alpha._value, 2.0e-6); BOOST_CHECK_EQUAL(alpha._epsilon, foxtrot._epsilon); - BOOST_CHECK(not (alpha._epsilon == gamma._epsilon)); + BOOST_CHECK(not(alpha._epsilon == gamma._epsilon)); // Test copy-constructor fp_compare_epsilon<double> charlie = fp_compare_epsilon<double>(alpha); @@ -60,45 +62,48 @@ BOOST_AUTO_TEST_CASE(double_compare_constructors) { BOOST_CHECK_EQUAL(alpha._epsilon, delta._epsilon); } -BOOST_AUTO_TEST_CASE(float_equality_operators) { +BOOST_AUTO_TEST_CASE(float_equality_operators) +{ // Test basic equality operator fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(1.0); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); BOOST_CHECK(alpha == beta); BOOST_CHECK(alpha == float(alpha._value)); // Test equality edge case at delta = epsilon - fp_compare_epsilon<float> charlie = fp_compare_epsilon<float>(alpha._value - + uhd::math::SINGLE_PRECISION_EPSILON); - BOOST_CHECK(not (alpha == charlie)); - BOOST_CHECK(not (alpha == float(alpha._value + uhd::math::SINGLE_PRECISION_EPSILON))); + fp_compare_epsilon<float> charlie = + fp_compare_epsilon<float>(alpha._value + uhd::math::SINGLE_PRECISION_EPSILON); + BOOST_CHECK(not(alpha == charlie)); + BOOST_CHECK(not(alpha == float(alpha._value + uhd::math::SINGLE_PRECISION_EPSILON))); } -BOOST_AUTO_TEST_CASE(double_equality_operators) { +BOOST_AUTO_TEST_CASE(double_equality_operators) +{ // Test basic equality operator fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(1.0); - fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); + fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); BOOST_CHECK(alpha == beta); BOOST_CHECK(alpha == double(beta._value)); // Test equality edge case at delta = epsilon - fp_compare_epsilon<double> charlie = fp_compare_epsilon<double>(alpha._value - + uhd::math::DOUBLE_PRECISION_EPSILON); - BOOST_CHECK(not (alpha == charlie)); - BOOST_CHECK(not (alpha == double(alpha._value - + uhd::math::DOUBLE_PRECISION_EPSILON))); + fp_compare_epsilon<double> charlie = + fp_compare_epsilon<double>(alpha._value + uhd::math::DOUBLE_PRECISION_EPSILON); + BOOST_CHECK(not(alpha == charlie)); + BOOST_CHECK(not(alpha == double(alpha._value + uhd::math::DOUBLE_PRECISION_EPSILON))); } -BOOST_AUTO_TEST_CASE(float_inequality_operators) { +BOOST_AUTO_TEST_CASE(float_inequality_operators) +{ // Test inequality operator, which is based on equality operator fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(127.0); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value + 1.19e-5f); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value + 1.19e-5f); BOOST_CHECK(alpha != beta); BOOST_CHECK(alpha != float(alpha._value + 1.19e-5f)); } -BOOST_AUTO_TEST_CASE(double_inequality_operators) { +BOOST_AUTO_TEST_CASE(double_inequality_operators) +{ // Test inequality operator, which is based on equality operator fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(1.0); fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value + 1.19e-10); @@ -107,10 +112,11 @@ BOOST_AUTO_TEST_CASE(double_inequality_operators) { BOOST_CHECK(alpha != double(alpha._value + 1.19e-10)); } -BOOST_AUTO_TEST_CASE(float_lessthan_operators) { +BOOST_AUTO_TEST_CASE(float_lessthan_operators) +{ // Test less-than operator fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(274192.7f); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value - 0.15f); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value - 0.15f); BOOST_CHECK(beta < alpha); BOOST_CHECK(float(alpha._value - 0.15) < alpha); @@ -118,29 +124,32 @@ BOOST_AUTO_TEST_CASE(float_lessthan_operators) { // Confirm false less-than case fp_compare_epsilon<float> charlie = fp_compare_epsilon<float>(alpha._value - 1.2f); - BOOST_CHECK(not (alpha < charlie)); - BOOST_CHECK(not (alpha < float(alpha._value - 1.2f))); + BOOST_CHECK(not(alpha < charlie)); + BOOST_CHECK(not(alpha < float(alpha._value - 1.2f))); } -BOOST_AUTO_TEST_CASE(double_lessthan_operators) { +BOOST_AUTO_TEST_CASE(double_lessthan_operators) +{ // Test less-than operator fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(274192856.762312); - fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value - 0.0002); + fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value - 0.0002); BOOST_CHECK(beta < alpha); BOOST_CHECK(double(alpha._value - 0.0002) < alpha); // Confirm false less-than case - fp_compare_epsilon<double> charlie = fp_compare_epsilon<double>(alpha._value - 1.0012); + fp_compare_epsilon<double> charlie = + fp_compare_epsilon<double>(alpha._value - 1.0012); - BOOST_CHECK(not (alpha < charlie)); - BOOST_CHECK(not (alpha < double(alpha._value - 1.0012))); + BOOST_CHECK(not(alpha < charlie)); + BOOST_CHECK(not(alpha < double(alpha._value - 1.0012))); } -BOOST_AUTO_TEST_CASE(float_lessthanequals_operators) { +BOOST_AUTO_TEST_CASE(float_lessthanequals_operators) +{ // Test that <= correctly reports for equal values fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(827.3f); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); BOOST_CHECK(alpha <= beta); BOOST_CHECK(alpha <= float(alpha._value)); @@ -152,25 +161,28 @@ BOOST_AUTO_TEST_CASE(float_lessthanequals_operators) { BOOST_CHECK(float(alpha._value - 1.2) <= alpha); } -BOOST_AUTO_TEST_CASE(double_lessthanequals_operators) { +BOOST_AUTO_TEST_CASE(double_lessthanequals_operators) +{ // Test that <= correctly reports for equal values fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(837652123.383764); - fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); + fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); BOOST_CHECK(alpha <= beta); BOOST_CHECK(alpha <= double(alpha._value)); // Test that <= correctly reports for less-than values - fp_compare_epsilon<double> charlie = fp_compare_epsilon<double>(alpha._value - 0.0012); + fp_compare_epsilon<double> charlie = + fp_compare_epsilon<double>(alpha._value - 0.0012); BOOST_CHECK(charlie <= alpha); BOOST_CHECK(double(alpha._value - 0.0012) <= alpha); } -BOOST_AUTO_TEST_CASE(float_greaterthan_operators) { +BOOST_AUTO_TEST_CASE(float_greaterthan_operators) +{ // Test basic greater-than functionality fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(98325.4f); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value + 0.15f); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value + 0.15f); BOOST_CHECK(beta > alpha); BOOST_CHECK(float(alpha._value + 0.15) > alpha); @@ -178,29 +190,32 @@ BOOST_AUTO_TEST_CASE(float_greaterthan_operators) { // Test false greater-than case fp_compare_epsilon<float> charlie = fp_compare_epsilon<float>(alpha._value + 1.2f); - BOOST_CHECK(not (alpha > charlie)); - BOOST_CHECK(not (alpha > float(alpha._value + 1.2f))); + BOOST_CHECK(not(alpha > charlie)); + BOOST_CHECK(not(alpha > float(alpha._value + 1.2f))); } -BOOST_AUTO_TEST_CASE(double_greaterthan_operators) { +BOOST_AUTO_TEST_CASE(double_greaterthan_operators) +{ // Test basic greater-than functionality fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(643907213.428475); - fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value + 0.0002); + fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value + 0.0002); BOOST_CHECK(beta > alpha); BOOST_CHECK(double(alpha._value + 0.0002) > alpha); // Test false greater-than case - fp_compare_epsilon<double> charlie = fp_compare_epsilon<double>(alpha._value + 0.0012); + fp_compare_epsilon<double> charlie = + fp_compare_epsilon<double>(alpha._value + 0.0012); - BOOST_CHECK(not (alpha > charlie)); - BOOST_CHECK(not (alpha > double(alpha._value + 0.0012))); + BOOST_CHECK(not(alpha > charlie)); + BOOST_CHECK(not(alpha > double(alpha._value + 0.0012))); } -BOOST_AUTO_TEST_CASE(float_greaterthanequals_operators) { +BOOST_AUTO_TEST_CASE(float_greaterthanequals_operators) +{ // Test that >= correctly reports for equal values fp_compare_epsilon<float> alpha = fp_compare_epsilon<float>(7834.89f); - fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); + fp_compare_epsilon<float> beta = fp_compare_epsilon<float>(alpha._value); BOOST_CHECK(alpha >= beta); BOOST_CHECK(alpha >= float(alpha._value)); @@ -212,16 +227,18 @@ BOOST_AUTO_TEST_CASE(float_greaterthanequals_operators) { BOOST_CHECK(float(alpha._value + 4.8f) >= alpha); } -BOOST_AUTO_TEST_CASE(double_greaterthanequals_operators) { +BOOST_AUTO_TEST_CASE(double_greaterthanequals_operators) +{ // Test that >= correctly reports for equal values fp_compare_epsilon<double> alpha = fp_compare_epsilon<double>(737623834.89843); - fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); + fp_compare_epsilon<double> beta = fp_compare_epsilon<double>(alpha._value); BOOST_CHECK(alpha >= beta); BOOST_CHECK(alpha >= double(alpha._value)); // Test that >= correctly reports for greater-than values - fp_compare_epsilon<double> charlie = fp_compare_epsilon<double>(alpha._value + 3.0008); + fp_compare_epsilon<double> charlie = + fp_compare_epsilon<double>(alpha._value + 3.0008); BOOST_CHECK(charlie >= alpha); BOOST_CHECK(double(alpha._value + 3.0008) >= alpha); diff --git a/host/tests/gain_group_test.cpp b/host/tests/gain_group_test.cpp index b8c15b479..2608f292d 100644 --- a/host/tests/gain_group_test.cpp +++ b/host/tests/gain_group_test.cpp @@ -5,10 +5,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/utils/gain_group.hpp> #include <boost/bind.hpp> #include <boost/math/special_functions/round.hpp> +#include <boost/test/unit_test.hpp> #include <iostream> #define rint(x) boost::math::iround(x) @@ -18,56 +18,63 @@ using namespace uhd; /*********************************************************************** * Define gain element classes with needed functions **********************************************************************/ -class gain_element1{ +class gain_element1 +{ public: - - gain_range_t get_range(void){ + gain_range_t get_range(void) + { return gain_range_t(0, 90, 1); } - double get_value(void){ + double get_value(void) + { return _gain; } - void set_value(double gain){ + void set_value(double gain) + { double step = get_range().step(); - _gain = step*rint(gain/step); + _gain = step * rint(gain / step); } private: double _gain; }; -class gain_element2{ +class gain_element2 +{ public: - - gain_range_t get_range(void){ + gain_range_t get_range(void) + { return gain_range_t(-20, 10, 0.1); } - double get_value(void){ + double get_value(void) + { return _gain; } - void set_value(double gain){ + void set_value(double gain) + { double step = get_range().step(); - _gain = step*rint(gain/step); + _gain = step * rint(gain / step); } private: double _gain; }; -//create static instances of gain elements to be shared by the tests +// create static instances of gain elements to be shared by the tests static gain_element1 g1; static gain_element2 g2; -static gain_group::sptr get_gain_group(size_t pri1 = 0, size_t pri2 = 0){ - //create instance of gain group +static gain_group::sptr get_gain_group(size_t pri1 = 0, size_t pri2 = 0) +{ + // create instance of gain group gain_fcns_t gain_fcns; gain_group::sptr gg(gain_group::make()); - //load gain group with function sets + // load gain group with function sets gain_fcns.get_range = boost::bind(&gain_element1::get_range, &g1); gain_fcns.get_value = boost::bind(&gain_element1::get_value, &g1); gain_fcns.set_value = boost::bind(&gain_element1::set_value, &g1, _1); @@ -86,10 +93,11 @@ static gain_group::sptr get_gain_group(size_t pri1 = 0, size_t pri2 = 0){ **********************************************************************/ static const double tolerance = 0.001; -BOOST_AUTO_TEST_CASE(test_gain_group_overall){ +BOOST_AUTO_TEST_CASE(test_gain_group_overall) +{ gain_group::sptr gg = get_gain_group(); - //test the overall stuff + // test the overall stuff gg->set_value(80); BOOST_CHECK_CLOSE(gg->get_value(), 80.0, tolerance); BOOST_CHECK_CLOSE(gg->get_range().start(), -20.0, tolerance); @@ -97,16 +105,17 @@ BOOST_AUTO_TEST_CASE(test_gain_group_overall){ BOOST_CHECK_CLOSE(gg->get_range().step(), 0.1, tolerance); } -BOOST_AUTO_TEST_CASE(test_gain_group_priority){ +BOOST_AUTO_TEST_CASE(test_gain_group_priority) +{ gain_group::sptr gg = get_gain_group(0, 1); - //test the overall stuff + // test the overall stuff gg->set_value(80); BOOST_CHECK_CLOSE(gg->get_value(), 80.0, tolerance); BOOST_CHECK_CLOSE(gg->get_range().start(), -20.0, tolerance); BOOST_CHECK_CLOSE(gg->get_range().stop(), 100.0, tolerance); BOOST_CHECK_CLOSE(gg->get_range().step(), 0.1, tolerance); - //test the the higher priority gain got filled first (gain 2) + // test the the higher priority gain got filled first (gain 2) BOOST_CHECK_CLOSE(g2.get_value(), g2.get_range().stop(), tolerance); } diff --git a/host/tests/graph.hpp b/host/tests/graph.hpp index 50a87d307..fb36ae510 100644 --- a/host/tests/graph.hpp +++ b/host/tests/graph.hpp @@ -15,23 +15,28 @@ #define MAKE_NODE(name) test_node::sptr name(new test_node(#name)); // Smallest possible test class -class test_node : virtual public uhd::rfnoc::sink_node_ctrl, virtual public uhd::rfnoc::source_node_ctrl +class test_node : virtual public uhd::rfnoc::sink_node_ctrl, + virtual public uhd::rfnoc::source_node_ctrl { public: typedef boost::shared_ptr<test_node> sptr; - test_node(const std::string &test_id) : _test_id(test_id) {}; + test_node(const std::string& test_id) : _test_id(test_id){}; - void issue_stream_cmd(const uhd::stream_cmd_t &, const size_t) {/* nop */}; + void issue_stream_cmd(const uhd::stream_cmd_t&, const size_t){/* nop */}; - std::string get_test_id() const { return _test_id; }; + std::string get_test_id() const + { + return _test_id; + }; private: const std::string _test_id; }; /* class test_node */ -void connect_nodes(uhd::rfnoc::source_node_ctrl::sptr A, uhd::rfnoc::sink_node_ctrl::sptr B) +void connect_nodes( + uhd::rfnoc::source_node_ctrl::sptr A, uhd::rfnoc::sink_node_ctrl::sptr B) { const size_t actual_src_port = A->connect_downstream(B); const size_t actual_dst_port = B->connect_upstream(A); diff --git a/host/tests/graph_search_test.cpp b/host/tests/graph_search_test.cpp index 8d35b3b1a..932647d98 100644 --- a/host/tests/graph_search_test.cpp +++ b/host/tests/graph_search_test.cpp @@ -17,7 +17,7 @@ class result_node : public test_node public: typedef boost::shared_ptr<result_node> sptr; - result_node(const std::string &test_id) : test_node(test_id) {}; + result_node(const std::string& test_id) : test_node(test_id){}; }; /* class result_node */ @@ -49,12 +49,12 @@ BOOST_AUTO_TEST_CASE(test_simple_downstream_search) connect_nodes(node_A, node_B1); // We're still searching for test_node, so any downstream block will match - std::vector< test_node::sptr > result = node_A->find_downstream_node<test_node>(); + std::vector<test_node::sptr> result = node_A->find_downstream_node<test_node>(); BOOST_REQUIRE(result.size() == 2); BOOST_CHECK( - (result[0]->get_test_id() == "node_B0" and result[1]->get_test_id() == "node_B1") or - (result[1]->get_test_id() == "node_B0" and result[0]->get_test_id() == "node_B1") - ); + (result[0]->get_test_id() == "node_B0" and result[1]->get_test_id() == "node_B1") + or (result[1]->get_test_id() == "node_B0" + and result[0]->get_test_id() == "node_B1")); BOOST_CHECK(result[0] == node_B0 or result[0] == node_B1); } @@ -69,11 +69,11 @@ BOOST_AUTO_TEST_CASE(test_linear_downstream_search) connect_nodes(node_B, node_C); // This time, we search for result_node - std::vector< result_node::sptr > result = node_A->find_downstream_node<result_node>(); + std::vector<result_node::sptr> result = node_A->find_downstream_node<result_node>(); std::cout << "size: " << result.size() << std::endl; BOOST_CHECK_EQUAL(result.size(), 1); BOOST_CHECK_EQUAL(result[0]->get_test_id(), "node_B"); - for(const result_node::sptr &node: result) { + for (const result_node::sptr& node : result) { std::cout << node->get_test_id() << std::endl; } } @@ -99,9 +99,9 @@ BOOST_AUTO_TEST_CASE(test_multi_iter_downstream_search) connect_nodes(node_C0, node_D0); // This time, we search for result_node - std::vector< result_node::sptr > result = node_A->find_downstream_node<result_node>(); + std::vector<result_node::sptr> result = node_A->find_downstream_node<result_node>(); BOOST_REQUIRE(result.size() == 4); - for(const result_node::sptr &node: result) { + for (const result_node::sptr& node : result) { std::cout << node->get_test_id() << std::endl; } } @@ -120,7 +120,8 @@ BOOST_AUTO_TEST_CASE(test_multi_iter_cycle_downstream_search) // Slightly more complex graph: connect_nodes(node_A, node_B0); // This connection goes both ways, causing a cycle - connect_nodes(node_A, node_B1); connect_nodes(node_B1, node_A); + connect_nodes(node_A, node_B1); + connect_nodes(node_B1, node_A); connect_nodes(node_B0, node_C0); connect_nodes(node_B0, node_C1); connect_nodes(node_B1, node_C2); @@ -128,9 +129,9 @@ BOOST_AUTO_TEST_CASE(test_multi_iter_cycle_downstream_search) connect_nodes(node_C0, node_D0); // This time, we search for result_node - std::vector< result_node::sptr > result = node_A->find_downstream_node<result_node>(); + std::vector<result_node::sptr> result = node_A->find_downstream_node<result_node>(); BOOST_REQUIRE(result.size() == 4); - for(const result_node::sptr &node: result) { + for (const result_node::sptr& node : result) { std::cout << node->get_test_id() << std::endl; } } @@ -141,9 +142,10 @@ BOOST_AUTO_TEST_CASE(test_mini_cycle_downstream_and_upstream) MAKE_NODE(node_B); // Connect them in a loop - connect_nodes(node_A, node_B); connect_nodes(node_B, node_A); + connect_nodes(node_A, node_B); + connect_nodes(node_B, node_A); - std::vector< test_node::sptr > result; + std::vector<test_node::sptr> result; result = node_A->find_downstream_node<test_node>(); BOOST_REQUIRE_EQUAL(result.size(), 1); BOOST_REQUIRE(result[0] == node_B); diff --git a/host/tests/log_test.cpp b/host/tests/log_test.cpp index 5e3ce0199..d9eae09f1 100644 --- a/host/tests/log_test.cpp +++ b/host/tests/log_test.cpp @@ -5,34 +5,25 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/log_add.hpp> +#include <boost/test/unit_test.hpp> #include <iostream> -BOOST_AUTO_TEST_CASE(test_messages){ +BOOST_AUTO_TEST_CASE(test_messages) +{ UHD_LOG_FASTPATH("foo"); UHD_LOG_FASTPATH("bar"); uhd::log::set_log_level(uhd::log::debug); uhd::log::set_console_level(uhd::log::info); - uhd::log::add_logger("test", - [](const uhd::log::logging_info &I){ - std::cout << "<TEST> " << I.message << std::endl; - } - ); + uhd::log::add_logger("test", [](const uhd::log::logging_info& I) { + std::cout << "<TEST> " << I.message << std::endl; + }); uhd::log::set_logger_level("test", uhd::log::debug); - UHD_LOGGER_DEBUG("logger_test") << - "This is a test print for a debug log." - ; - UHD_LOGGER_INFO("logger_test") << - "This is a test print for a info log." - ; - UHD_LOGGER_WARNING("logger_test") << - "This is a test print for a warning log." - ; - UHD_LOGGER_ERROR("logger_test") << - "This is a test print for an error log." - ; + UHD_LOGGER_DEBUG("logger_test") << "This is a test print for a debug log."; + UHD_LOGGER_INFO("logger_test") << "This is a test print for a info log."; + UHD_LOGGER_WARNING("logger_test") << "This is a test print for a warning log."; + UHD_LOGGER_ERROR("logger_test") << "This is a test print for an error log."; UHD_HERE(); const int x = 42; UHD_VAR(x); diff --git a/host/tests/math_test.cpp b/host/tests/math_test.cpp index 131016091..ffdcbb086 100644 --- a/host/tests/math_test.cpp +++ b/host/tests/math_test.cpp @@ -5,15 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> -#include <stdint.h> #include <uhd/utils/math.hpp> +#include <stdint.h> +#include <boost/test/unit_test.hpp> // NOTE: This is not the only math test case, see e.g. special tests // for fp comparison. -BOOST_AUTO_TEST_CASE(test_log2){ +BOOST_AUTO_TEST_CASE(test_log2) +{ double y = uhd::math::log2(16.0); BOOST_CHECK_EQUAL(y, 4.0); } - diff --git a/host/tests/module_test.cpp b/host/tests/module_test.cpp index 8914c56a1..c81d8563f 100644 --- a/host/tests/module_test.cpp +++ b/host/tests/module_test.cpp @@ -8,7 +8,8 @@ #include <uhd/utils/static.hpp> #include <iostream> -UHD_STATIC_BLOCK(module_test){ +UHD_STATIC_BLOCK(module_test) +{ std::cout << "---------------------------------------" << std::endl; std::cout << "-- Good news, everyone!" << std::endl; std::cout << "-- The test module has been loaded." << std::endl; diff --git a/host/tests/narrow_cast_test.cpp b/host/tests/narrow_cast_test.cpp index c108c310e..3ea7db1bf 100644 --- a/host/tests/narrow_cast_test.cpp +++ b/host/tests/narrow_cast_test.cpp @@ -11,11 +11,12 @@ using namespace uhd; -BOOST_AUTO_TEST_CASE(test_narrow){ +BOOST_AUTO_TEST_CASE(test_narrow) +{ uint16_t x = 5; - uint8_t y = narrow_cast<uint8_t>(x); + uint8_t y = narrow_cast<uint8_t>(x); BOOST_CHECK_EQUAL(x, y); - BOOST_CHECK_THROW(narrow<uint8_t>(uint16_t(1<<10)), narrowing_error); + BOOST_CHECK_THROW(narrow<uint8_t>(uint16_t(1 << 10)), narrowing_error); BOOST_CHECK_THROW(narrow<uint8_t>(int8_t(-1)), narrowing_error); } diff --git a/host/tests/nocscript_common.hpp b/host/tests/nocscript_common.hpp index 4176fec6f..ad254fa0e 100644 --- a/host/tests/nocscript_common.hpp +++ b/host/tests/nocscript_common.hpp @@ -11,15 +11,20 @@ using namespace uhd::rfnoc::nocscript; // Some global defs to make tests easier to write -expression_function::argtype_list_type one_int_arg = boost::assign::list_of(expression::TYPE_INT); -expression_function::argtype_list_type two_int_args = boost::assign::list_of(expression::TYPE_INT)(expression::TYPE_INT); -expression_function::argtype_list_type one_double_arg = boost::assign::list_of(expression::TYPE_DOUBLE); -expression_function::argtype_list_type two_double_args = boost::assign::list_of(expression::TYPE_DOUBLE)(expression::TYPE_DOUBLE); -expression_function::argtype_list_type one_bool_arg = boost::assign::list_of(expression::TYPE_BOOL); -expression_function::argtype_list_type two_bool_args = boost::assign::list_of(expression::TYPE_BOOL)(expression::TYPE_BOOL); +expression_function::argtype_list_type one_int_arg = + boost::assign::list_of(expression::TYPE_INT); +expression_function::argtype_list_type two_int_args = + boost::assign::list_of(expression::TYPE_INT)(expression::TYPE_INT); +expression_function::argtype_list_type one_double_arg = + boost::assign::list_of(expression::TYPE_DOUBLE); +expression_function::argtype_list_type two_double_args = + boost::assign::list_of(expression::TYPE_DOUBLE)(expression::TYPE_DOUBLE); +expression_function::argtype_list_type one_bool_arg = + boost::assign::list_of(expression::TYPE_BOOL); +expression_function::argtype_list_type two_bool_args = + boost::assign::list_of(expression::TYPE_BOOL)(expression::TYPE_BOOL); expression_function::argtype_list_type no_args; expression_container::expr_list_type empty_arg_list; #define E(x) expression_literal::make(x) - diff --git a/host/tests/nocscript_expr_test.cpp b/host/tests/nocscript_expr_test.cpp index 19b4345c2..ed5f6598d 100644 --- a/host/tests/nocscript_expr_test.cpp +++ b/host/tests/nocscript_expr_test.cpp @@ -6,16 +6,15 @@ // #include "../lib/rfnoc/nocscript/function_table.hpp" -#include <boost/test/unit_test.hpp> -#include <boost/test/floating_point_comparison.hpp> +#include "nocscript_common.hpp" #include <boost/bind.hpp> -#include <boost/make_shared.hpp> #include <boost/format.hpp> +#include <boost/make_shared.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/test/unit_test.hpp> #include <algorithm> #include <iostream> -#include "nocscript_common.hpp" - // We need this global variable for one of the later tests int and_counter = 0; @@ -65,15 +64,15 @@ BOOST_AUTO_TEST_CASE(test_literals) BOOST_CHECK_EQUAL(literal_int_vec.infer_type(), expression::TYPE_INT_VECTOR); std::vector<int> test_data{1, 2, 3}; std::vector<int> result = literal_int_vec.get_int_vector(); - BOOST_CHECK_EQUAL_COLLECTIONS(test_data.begin(), test_data.end(), - result.begin(), result.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( + test_data.begin(), test_data.end(), result.begin(), result.end()); BOOST_REQUIRE_THROW(literal_int_vec.get_bool(), uhd::type_error); BOOST_REQUIRE_THROW(literal_int_vec.get_int(), uhd::type_error); } // Need those for the variable testing: -expression::type_t variable_get_type(const std::string &var_name) +expression::type_t variable_get_type(const std::string& var_name) { if (var_name == "spp") { std::cout << "Returning type for $spp..." << std::endl; @@ -87,7 +86,7 @@ expression::type_t variable_get_type(const std::string &var_name) throw uhd::syntax_error("Cannot infer type (unknown variable)"); } -expression_literal variable_get_value(const std::string &var_name) +expression_literal variable_get_value(const std::string& var_name) { if (var_name == "spp") { std::cout << "Returning value for $spp..." << std::endl; @@ -103,18 +102,14 @@ expression_literal variable_get_value(const std::string &var_name) BOOST_AUTO_TEST_CASE(test_variables) { - BOOST_REQUIRE_THROW( - expression_variable v_fail( - "foo", // Invalid token - boost::bind(&variable_get_type, _1), boost::bind(&variable_get_value, _1) - ), - uhd::assertion_error - ); - - expression_variable v( - "$spp", // The token - boost::bind(&variable_get_type, _1), // type-getter - boost::bind(&variable_get_value, _1) // value-getter + BOOST_REQUIRE_THROW(expression_variable v_fail("foo", // Invalid token + boost::bind(&variable_get_type, _1), + boost::bind(&variable_get_value, _1)), + uhd::assertion_error); + + expression_variable v("$spp", // The token + boost::bind(&variable_get_type, _1), // type-getter + boost::bind(&variable_get_value, _1) // value-getter ); BOOST_CHECK_EQUAL(v.infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(v.eval().get_int(), 5); @@ -123,23 +118,21 @@ BOOST_AUTO_TEST_CASE(test_variables) BOOST_AUTO_TEST_CASE(test_container) { // Create some sub-expressions: - expression_literal::sptr l_true = E(true); + expression_literal::sptr l_true = E(true); expression_literal::sptr l_false = E(false); - expression_literal::sptr l_int = E(5); + expression_literal::sptr l_int = E(5); BOOST_REQUIRE_EQUAL(l_false->get_bool(), false); BOOST_REQUIRE_EQUAL(l_false->to_bool(), false); - expression_variable::sptr l_boolvar = boost::make_shared<expression_variable>( - "$is_true", - boost::bind(&variable_get_type, _1), - boost::bind(&variable_get_value, _1) - ); + expression_variable::sptr l_boolvar = + boost::make_shared<expression_variable>("$is_true", + boost::bind(&variable_get_type, _1), + boost::bind(&variable_get_value, _1)); // This will throw anytime it's evaluated: - expression_variable::sptr l_failvar = boost::make_shared<expression_variable>( - "$does_not_exist", - boost::bind(&variable_get_type, _1), - boost::bind(&variable_get_value, _1) - ); + expression_variable::sptr l_failvar = + boost::make_shared<expression_variable>("$does_not_exist", + boost::bind(&variable_get_type, _1), + boost::bind(&variable_get_value, _1)); expression_container c; std::cout << "One true, OR: " << std::endl; @@ -196,38 +189,32 @@ BOOST_AUTO_TEST_CASE(test_container) // be defined for INT and DOUBLE class functable_mockup_impl : public function_table { - public: - functable_mockup_impl(void) {}; +public: + functable_mockup_impl(void){}; - bool function_exists(const std::string &name) const { + bool function_exists(const std::string& name) const + { return name == "ADD" or name == "XOR" or name == "AND"; } - bool function_exists( - const std::string &name, - const expression_function::argtype_list_type &arg_types - ) const { + bool function_exists(const std::string& name, + const expression_function::argtype_list_type& arg_types) const + { if (name == "ADD") { - if (arg_types.size() == 2 - and arg_types[0] == expression::TYPE_DOUBLE - and arg_types[1] == expression::TYPE_DOUBLE - ) { + if (arg_types.size() == 2 and arg_types[0] == expression::TYPE_DOUBLE + and arg_types[1] == expression::TYPE_DOUBLE) { return true; } - if (arg_types.size() == 2 - and arg_types[0] == expression::TYPE_INT - and arg_types[1] == expression::TYPE_INT - ) { + if (arg_types.size() == 2 and arg_types[0] == expression::TYPE_INT + and arg_types[1] == expression::TYPE_INT) { return true; } return false; } if (name == "XOR" or name == "AND") { - if (arg_types.size() == 2 - and arg_types[0] == expression::TYPE_BOOL - and arg_types[1] == expression::TYPE_BOOL - ) { + if (arg_types.size() == 2 and arg_types[0] == expression::TYPE_BOOL + and arg_types[1] == expression::TYPE_BOOL) { return true; } return false; @@ -236,15 +223,14 @@ class functable_mockup_impl : public function_table return false; } - expression::type_t get_type( - const std::string &name, - const expression_function::argtype_list_type &arg_types - ) const { + expression::type_t get_type(const std::string& name, + const expression_function::argtype_list_type& arg_types) const + { if (not function_exists(name, arg_types)) { - throw uhd::syntax_error(str( - boost::format("[EXPR_TEXT] get_type(): Unknown function: %s, %d arguments") - % name % arg_types.size() - )); + throw uhd::syntax_error( + str(boost::format( + "[EXPR_TEXT] get_type(): Unknown function: %s, %d arguments") + % name % arg_types.size())); } if (name == "XOR" or name == "AND") { @@ -256,58 +242,48 @@ class functable_mockup_impl : public function_table UHD_THROW_INVALID_CODE_PATH(); } - expression_literal eval( - const std::string &name, - const expression_function::argtype_list_type &arg_types, - expression_container::expr_list_type &args - ) { + expression_literal eval(const std::string& name, + const expression_function::argtype_list_type& arg_types, + expression_container::expr_list_type& args) + { if (name == "XOR") { - if (arg_types.size() != 2 - or args.size() != 2 + if (arg_types.size() != 2 or args.size() != 2 or arg_types[0] != expression::TYPE_BOOL or arg_types[1] != expression::TYPE_BOOL or args[0]->infer_type() != expression::TYPE_BOOL - or args[1]->infer_type() != expression::TYPE_BOOL - ) { + or args[1]->infer_type() != expression::TYPE_BOOL) { throw uhd::syntax_error("eval(): XOR type mismatch"); } - return expression_literal(bool( - args[0]->eval().get_bool() xor args[1]->eval().get_bool() - )); + return expression_literal( + bool(args[0]->eval().get_bool() xor args[1]->eval().get_bool())); } if (name == "AND") { - if (arg_types.size() != 2 - or args.size() != 2 + if (arg_types.size() != 2 or args.size() != 2 or arg_types[0] != expression::TYPE_BOOL or arg_types[1] != expression::TYPE_BOOL or args[0]->infer_type() != expression::TYPE_BOOL - or args[1]->infer_type() != expression::TYPE_BOOL - ) { + or args[1]->infer_type() != expression::TYPE_BOOL) { throw uhd::syntax_error("eval(): AND type mismatch"); } std::cout << "Calling AND" << std::endl; and_counter++; - return expression_literal(bool( - args[0]->eval().get_bool() and args[1]->eval().get_bool() - )); + return expression_literal( + bool(args[0]->eval().get_bool() and args[1]->eval().get_bool())); } if (name == "ADD") { if (args.size() != 2) { throw uhd::syntax_error("eval(): ADD type mismatch"); } - if ((args[0]->infer_type() == expression::TYPE_INT) and - (args[1]->infer_type() == expression::TYPE_INT)) { - return expression_literal(int( - args[0]->eval().get_int() + args[1]->eval().get_int() - )); - } - else if ((args[0]->infer_type() == expression::TYPE_DOUBLE) and - (args[1]->infer_type() == expression::TYPE_DOUBLE)) { - return expression_literal(double( - args[0]->eval().get_double() + args[1]->eval().get_double() - )); + if ((args[0]->infer_type() == expression::TYPE_INT) + and (args[1]->infer_type() == expression::TYPE_INT)) { + return expression_literal( + int(args[0]->eval().get_int() + args[1]->eval().get_int())); + } else if ((args[0]->infer_type() == expression::TYPE_DOUBLE) + and (args[1]->infer_type() == expression::TYPE_DOUBLE)) { + return expression_literal( + double(args[0]->eval().get_double() + args[1]->eval().get_double())); } throw uhd::syntax_error("eval(): ADD type mismatch"); } @@ -315,13 +291,10 @@ class functable_mockup_impl : public function_table } // We don't actually need this - void register_function( - const std::string &, - const function_table::function_ptr &, - const expression::type_t, - const expression_function::argtype_list_type & - ) {}; - + void register_function(const std::string&, + const function_table::function_ptr&, + const expression::type_t, + const expression_function::argtype_list_type&){}; }; @@ -342,16 +315,20 @@ BOOST_AUTO_TEST_CASE(test_functable_mockup) BOOST_CHECK(not functable.function_exists("XOR", no_args)); BOOST_CHECK_EQUAL(functable.get_type("ADD", two_int_args), expression::TYPE_INT); - BOOST_CHECK_EQUAL(functable.get_type("ADD", two_double_args), expression::TYPE_DOUBLE); + BOOST_CHECK_EQUAL( + functable.get_type("ADD", two_double_args), expression::TYPE_DOUBLE); BOOST_CHECK_EQUAL(functable.get_type("XOR", two_bool_args), expression::TYPE_BOOL); expression_container::expr_list_type add_args_int{E(2), E(3)}; expression_container::expr_list_type add_args_dbl{E(2.25), E(5.0)}; expression_container::expr_list_type xor_args_bool{E(true), E(false)}; - BOOST_CHECK_EQUAL(functable.eval("ADD", two_int_args, add_args_int), expression_literal(5)); - BOOST_CHECK_EQUAL(functable.eval("ADD", two_double_args, add_args_dbl), expression_literal(7.25)); - BOOST_CHECK_EQUAL(functable.eval("XOR", two_bool_args, xor_args_bool), expression_literal(true)); + BOOST_CHECK_EQUAL( + functable.eval("ADD", two_int_args, add_args_int), expression_literal(5)); + BOOST_CHECK_EQUAL( + functable.eval("ADD", two_double_args, add_args_dbl), expression_literal(7.25)); + BOOST_CHECK_EQUAL( + functable.eval("XOR", two_bool_args, xor_args_bool), expression_literal(true)); } BOOST_AUTO_TEST_CASE(test_function_expression) @@ -402,7 +379,7 @@ BOOST_AUTO_TEST_CASE(test_function_expression_laziness) f3->add(E(false)); BOOST_CHECK(not f3->eval().get_bool()); - and_counter = 0; + and_counter = 0; expression_function::sptr f1 = boost::make_shared<expression_function>("AND", ft); f1->add(f2); f1->add(f3); @@ -417,14 +394,12 @@ BOOST_AUTO_TEST_CASE(test_sptrs) BOOST_CHECK_EQUAL(c->infer_type(), expression::TYPE_BOOL); BOOST_CHECK(c->eval().get_bool()); - expression_variable::sptr v = expression_variable::make( - "$spp", - boost::bind(&variable_get_type, _1), // type-getter - boost::bind(&variable_get_value, _1) // value-getter + expression_variable::sptr v = expression_variable::make("$spp", + boost::bind(&variable_get_type, _1), // type-getter + boost::bind(&variable_get_value, _1) // value-getter ); c->add(v); BOOST_REQUIRE_EQUAL(c->infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(c->eval().get_int(), 5); } - diff --git a/host/tests/nocscript_ftable_test.cpp b/host/tests/nocscript_ftable_test.cpp index 99ac2231a..36aa314f2 100644 --- a/host/tests/nocscript_ftable_test.cpp +++ b/host/tests/nocscript_ftable_test.cpp @@ -6,15 +6,14 @@ // #include "../lib/rfnoc/nocscript/function_table.hpp" -#include <boost/test/unit_test.hpp> -#include <boost/test/floating_point_comparison.hpp> +#include "nocscript_common.hpp" #include <boost/bind.hpp> #include <boost/make_shared.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/test/unit_test.hpp> #include <algorithm> #include <iostream> -#include "nocscript_common.hpp" - BOOST_AUTO_TEST_CASE(test_basic_funcs) { function_table::sptr ft = function_table::make(); @@ -49,7 +48,7 @@ BOOST_AUTO_TEST_CASE(test_basic_funcs) BOOST_REQUIRE_EQUAL(ft->get_type("DIV", two_double_args), expression::TYPE_DOUBLE); expression_literal e_div_d = ft->eval("DIV", two_double_args, two_double_values); BOOST_REQUIRE_EQUAL(e_div_d.infer_type(), expression::TYPE_DOUBLE); - BOOST_CHECK_CLOSE(e_div_d.get_double(), 2.0/3.0, 0.01); + BOOST_CHECK_CLOSE(e_div_d.get_double(), 2.0 / 3.0, 0.01); BOOST_REQUIRE_EQUAL(ft->get_type("MODULO", two_int_args), expression::TYPE_INT); expression_literal e_modulo_i = ft->eval("MODULO", two_int_args, two_int_values); @@ -103,15 +102,11 @@ BOOST_AUTO_TEST_CASE(test_add_funcs) BOOST_CHECK(not ft->function_exists("ADD_PLUS_2")); expression_function::argtype_list_type add_int_args{ + expression::TYPE_INT, expression::TYPE_INT}; + ft->register_function("ADD_PLUS_2", + boost::bind(&add_plus2_int, _1), expression::TYPE_INT, - expression::TYPE_INT - }; - ft->register_function( - "ADD_PLUS_2", - boost::bind(&add_plus2_int, _1), - expression::TYPE_INT, - add_int_args - ); + add_int_args); BOOST_CHECK(ft->function_exists("ADD_PLUS_2")); BOOST_CHECK(ft->function_exists("ADD_PLUS_2", add_int_args)); @@ -144,22 +139,16 @@ BOOST_AUTO_TEST_CASE(test_conditionals) { function_table::sptr ft = function_table::make(); ft->register_function( - "DUMMY", - boost::bind(&dummy_true, _1), - expression::TYPE_BOOL, - no_args - ); + "DUMMY", boost::bind(&dummy_true, _1), expression::TYPE_BOOL, no_args); ft->register_function( - "DUMMY_F", - boost::bind(&dummy_false, _1), - expression::TYPE_BOOL, - no_args - ); + "DUMMY_F", boost::bind(&dummy_false, _1), expression::TYPE_BOOL, no_args); BOOST_REQUIRE(ft->function_exists("DUMMY", no_args)); BOOST_REQUIRE(ft->function_exists("DUMMY_F", no_args)); - expression_function::sptr dummy_statement = boost::make_shared<expression_function>("DUMMY", ft); - expression_function::sptr if_statement = boost::make_shared<expression_function>("IF", ft); + expression_function::sptr dummy_statement = + boost::make_shared<expression_function>("DUMMY", ft); + expression_function::sptr if_statement = + boost::make_shared<expression_function>("IF", ft); if_statement->add(E(true)); if_statement->add(dummy_statement); @@ -170,7 +159,8 @@ BOOST_AUTO_TEST_CASE(test_conditionals) std::cout << "END." << std::endl; std::cout << "Dummy statement should not run until END:" << std::endl; - expression_function::sptr if_statement2 = boost::make_shared<expression_function>("IF", ft); + expression_function::sptr if_statement2 = + boost::make_shared<expression_function>("IF", ft); if_statement2->add(E(false)); if_statement2->add(dummy_statement); dummy_true_counter = 0; @@ -178,12 +168,14 @@ BOOST_AUTO_TEST_CASE(test_conditionals) BOOST_CHECK_EQUAL(dummy_true_counter, 0); std::cout << "END." << std::endl; - expression_function::sptr if_else_statement = boost::make_shared<expression_function>("IF_ELSE", ft); - expression_function::sptr dummy_statement_f = boost::make_shared<expression_function>("DUMMY_F", ft); + expression_function::sptr if_else_statement = + boost::make_shared<expression_function>("IF_ELSE", ft); + expression_function::sptr dummy_statement_f = + boost::make_shared<expression_function>("DUMMY_F", ft); if_else_statement->add(E(true)); if_else_statement->add(dummy_statement); if_else_statement->add(dummy_statement_f); - dummy_true_counter = 0; + dummy_true_counter = 0; dummy_false_counter = 0; std::cout << "Should execute dummy/true statement before END:" << std::endl; BOOST_CHECK(if_else_statement->eval().get_bool()); @@ -191,11 +183,12 @@ BOOST_AUTO_TEST_CASE(test_conditionals) BOOST_CHECK_EQUAL(dummy_false_counter, 0); std::cout << "END." << std::endl; - expression_function::sptr if_else_statement2 = boost::make_shared<expression_function>("IF_ELSE", ft); + expression_function::sptr if_else_statement2 = + boost::make_shared<expression_function>("IF_ELSE", ft); if_else_statement2->add(E(false)); if_else_statement2->add(dummy_statement); if_else_statement2->add(dummy_statement_f); - dummy_true_counter = 0; + dummy_true_counter = 0; dummy_false_counter = 0; std::cout << "Should execute dummy/false statement before END:" << std::endl; BOOST_CHECK(not if_else_statement2->eval().get_bool()); @@ -221,33 +214,35 @@ BOOST_AUTO_TEST_CASE(test_bitwise_funcs) // Bitwise Math int int_value1 = 0x2; int int_value2 = 0x3; - expression_container::expr_list_type two_int_values{ - E(int_value1), - E(int_value2) - }; + expression_container::expr_list_type two_int_values{E(int_value1), E(int_value2)}; BOOST_REQUIRE_EQUAL(ft->get_type("SHIFT_RIGHT", two_int_args), expression::TYPE_INT); - expression_literal e_shift_right = ft->eval("SHIFT_RIGHT", two_int_args, two_int_values); + expression_literal e_shift_right = + ft->eval("SHIFT_RIGHT", two_int_args, two_int_values); BOOST_REQUIRE_EQUAL(e_shift_right.infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(e_shift_right.get_int(), int_value1 >> int_value2); BOOST_REQUIRE_EQUAL(ft->get_type("SHIFT_LEFT", two_int_args), expression::TYPE_INT); - expression_literal e_shift_left = ft->eval("SHIFT_LEFT", two_int_args, two_int_values); + expression_literal e_shift_left = + ft->eval("SHIFT_LEFT", two_int_args, two_int_values); BOOST_REQUIRE_EQUAL(e_shift_left.infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(e_shift_left.get_int(), int_value1 << int_value2); BOOST_REQUIRE_EQUAL(ft->get_type("BITWISE_AND", two_int_args), expression::TYPE_INT); - expression_literal e_bitwise_and = ft->eval("BITWISE_AND", two_int_args, two_int_values); + expression_literal e_bitwise_and = + ft->eval("BITWISE_AND", two_int_args, two_int_values); BOOST_REQUIRE_EQUAL(e_bitwise_and.infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(e_bitwise_and.get_int(), int_value1 & int_value2); BOOST_REQUIRE_EQUAL(ft->get_type("BITWISE_OR", two_int_args), expression::TYPE_INT); - expression_literal e_bitwise_or = ft->eval("BITWISE_OR", two_int_args, two_int_values); + expression_literal e_bitwise_or = + ft->eval("BITWISE_OR", two_int_args, two_int_values); BOOST_REQUIRE_EQUAL(e_bitwise_or.infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(e_bitwise_or.get_int(), int_value1 | int_value2); BOOST_REQUIRE_EQUAL(ft->get_type("BITWISE_XOR", two_int_args), expression::TYPE_INT); - expression_literal e_bitwise_xor = ft->eval("BITWISE_XOR", two_int_args, two_int_values); + expression_literal e_bitwise_xor = + ft->eval("BITWISE_XOR", two_int_args, two_int_values); BOOST_REQUIRE_EQUAL(e_bitwise_xor.infer_type(), expression::TYPE_INT); BOOST_CHECK_EQUAL(e_bitwise_xor.get_int(), int_value1 ^ int_value2); } diff --git a/host/tests/nocscript_parser_test.cpp b/host/tests/nocscript_parser_test.cpp index caa2ae6e0..eb9352995 100644 --- a/host/tests/nocscript_parser_test.cpp +++ b/host/tests/nocscript_parser_test.cpp @@ -7,21 +7,20 @@ #include "../lib/rfnoc/nocscript/function_table.hpp" #include "../lib/rfnoc/nocscript/parser.hpp" +#include "nocscript_common.hpp" #include <uhd/exception.hpp> -#include <boost/test/unit_test.hpp> -#include <boost/test/floating_point_comparison.hpp> #include <boost/assign/list_of.hpp> #include <boost/bind.hpp> #include <boost/make_shared.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/test/unit_test.hpp> #include <algorithm> #include <iostream> -#include "nocscript_common.hpp" - const int SPP_VALUE = 64; // Need those for the variable testing: -expression::type_t variable_get_type(const std::string &var_name) +expression::type_t variable_get_type(const std::string& var_name) { if (var_name == "spp") { std::cout << "Returning type for $spp..." << std::endl; @@ -35,7 +34,7 @@ expression::type_t variable_get_type(const std::string &var_name) throw uhd::syntax_error("Cannot infer type (unknown variable)"); } -expression_literal variable_get_value(const std::string &var_name) +expression_literal variable_get_value(const std::string& var_name) { if (var_name == "spp") { std::cout << "Returning value for $spp..." << std::endl; @@ -49,13 +48,10 @@ expression_literal variable_get_value(const std::string &var_name) throw uhd::syntax_error("Cannot read value (unknown variable)"); } -#define SETUP_FT_AND_PARSER() \ +#define SETUP_FT_AND_PARSER() \ function_table::sptr ft = function_table::make(); \ - parser::sptr p = parser::make( \ - ft, \ - boost::bind(&variable_get_type, _1), \ - boost::bind(&variable_get_value, _1) \ - ); + parser::sptr p = parser::make( \ + ft, boost::bind(&variable_get_type, _1), boost::bind(&variable_get_value, _1)); BOOST_AUTO_TEST_CASE(test_fail) { @@ -79,11 +75,11 @@ BOOST_AUTO_TEST_CASE(test_adds_no_vars) BOOST_REQUIRE(ft->function_exists("ADD")); const std::string line("ADD(1, ADD(2, ADD(3, 4)))"); - expression::sptr e = p->create_expr_tree(line); + expression::sptr e = p->create_expr_tree(line); expression_literal result = e->eval(); BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_INT); - BOOST_CHECK_EQUAL(result.get_int(), 1+2+3+4); + BOOST_CHECK_EQUAL(result.get_int(), 1 + 2 + 3 + 4); } BOOST_AUTO_TEST_CASE(test_adds_with_vars) @@ -91,11 +87,11 @@ BOOST_AUTO_TEST_CASE(test_adds_with_vars) SETUP_FT_AND_PARSER(); const std::string line("ADD(1, ADD(2, $spp))"); - expression::sptr e = p->create_expr_tree(line); + expression::sptr e = p->create_expr_tree(line); expression_literal result = e->eval(); BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_INT); - BOOST_CHECK_EQUAL(result.get_int(), 1+2+SPP_VALUE); + BOOST_CHECK_EQUAL(result.get_int(), 1 + 2 + SPP_VALUE); } BOOST_AUTO_TEST_CASE(test_fft_check) @@ -103,7 +99,7 @@ BOOST_AUTO_TEST_CASE(test_fft_check) SETUP_FT_AND_PARSER(); const std::string line("GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)"); - expression::sptr e = p->create_expr_tree(line); + expression::sptr e = p->create_expr_tree(line); expression_literal result = e->eval(); BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_BOOL); @@ -135,11 +131,7 @@ BOOST_AUTO_TEST_CASE(test_multi_commmand) SETUP_FT_AND_PARSER(); ft->register_function( - "DUMMY", - boost::bind(&dummy_false, _1), - expression::TYPE_BOOL, - no_args - ); + "DUMMY", boost::bind(&dummy_false, _1), expression::TYPE_BOOL, no_args); dummy_false_counter = 0; p->create_expr_tree("DUMMY(), DUMMY(), DUMMY()")->eval(); @@ -153,4 +145,3 @@ BOOST_AUTO_TEST_CASE(test_multi_commmand) p->create_expr_tree("DUMMY() OR DUMMY() OR DUMMY()")->eval(); BOOST_CHECK_EQUAL(dummy_false_counter, 3); } - diff --git a/host/tests/node_connect_test.cpp b/host/tests/node_connect_test.cpp index dd3d8d08a..97d052a06 100644 --- a/host/tests/node_connect_test.cpp +++ b/host/tests/node_connect_test.cpp @@ -16,25 +16,22 @@ class source_node : public test_node public: typedef boost::shared_ptr<source_node> sptr; - source_node(const std::string &test_id, size_t output_port) - : test_node(test_id) - , active_rx_streamer_on_port(0) - , _output_port(output_port) {}; + source_node(const std::string& test_id, size_t output_port) + : test_node(test_id), active_rx_streamer_on_port(0), _output_port(output_port){}; void set_rx_streamer(bool active, const size_t port) { if (active) { - std::cout << "[source_node] Someone is registering a rx streamer on port " << port << std::endl; + std::cout << "[source_node] Someone is registering a rx streamer on port " + << port << std::endl; active_rx_streamer_on_port = port; } } size_t active_rx_streamer_on_port; protected: - size_t _request_output_port( - const size_t, - const uhd::device_addr_t & - ) const { + size_t _request_output_port(const size_t, const uhd::device_addr_t&) const + { return _output_port; } @@ -47,25 +44,22 @@ class sink_node : public test_node public: typedef boost::shared_ptr<sink_node> sptr; - sink_node(const std::string &test_id, size_t input_port) - : test_node(test_id) - , active_tx_streamer_on_port(0) - , _input_port(input_port) {}; + sink_node(const std::string& test_id, size_t input_port) + : test_node(test_id), active_tx_streamer_on_port(0), _input_port(input_port){}; void set_tx_streamer(bool active, const size_t port) { if (active) { - std::cout << "[sink_node] Someone is registering a tx streamer on port " << port << std::endl; + std::cout << "[sink_node] Someone is registering a tx streamer on port " + << port << std::endl; active_tx_streamer_on_port = port; } } size_t active_tx_streamer_on_port; protected: - size_t _request_input_port( - const size_t, - const uhd::device_addr_t & - ) const { + size_t _request_input_port(const size_t, const uhd::device_addr_t&) const + { return _input_port; } diff --git a/host/tests/packet_handler_benchmark.cpp b/host/tests/packet_handler_benchmark.cpp index 37c6861bb..21e1430ae 100644 --- a/host/tests/packet_handler_benchmark.cpp +++ b/host/tests/packet_handler_benchmark.cpp @@ -11,16 +11,16 @@ // This should have very little effect on packet handler performance. #define SRPH_DONT_CHECK_SEQUENCE 1 -#include "common/mock_zero_copy.hpp" -#include "../lib/transport/super_send_packet_handler.hpp" #include "../lib/transport/super_recv_packet_handler.hpp" +#include "../lib/transport/super_send_packet_handler.hpp" #include "../lib/usrp/device3/device3_flow_ctrl.hpp" -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/thread.hpp> +#include "common/mock_zero_copy.hpp" #include <uhd/convert.hpp> #include <uhd/transport/chdr.hpp> #include <uhd/transport/zero_copy.hpp> #include <uhd/types/sid.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/program_options.hpp> #include <chrono> #include <vector> @@ -29,18 +29,13 @@ namespace po = boost::program_options; using namespace uhd::transport; using namespace uhd::usrp; -void benchmark_recv_packet_handler( - const size_t spp, - const std::string& format -) { - const size_t bpi = uhd::convert::get_bytes_per_item(format); +void benchmark_recv_packet_handler(const size_t spp, const std::string& format) +{ + const size_t bpi = uhd::convert::get_bytes_per_item(format); const size_t frame_size = bpi * spp + DEVICE3_RX_MAX_HDR_LEN; - mock_zero_copy::sptr xport( - new mock_zero_copy( - vrt::if_packet_info_t::LINK_TYPE_CHDR, - frame_size, - frame_size)); + mock_zero_copy::sptr xport(new mock_zero_copy( + vrt::if_packet_info_t::LINK_TYPE_CHDR, frame_size, frame_size)); xport->set_reuse_recv_memory(true); @@ -51,38 +46,35 @@ void benchmark_recv_packet_handler( uhd::convert::id_type id; id.output_format = format; - id.num_inputs = 1; - id.input_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_outputs = 1; streamer.set_converter(id); - streamer.set_xport_chan_get_buff( - 0, - [xport](double timeout) { - return xport->get_recv_buff(timeout); - }, + streamer.set_xport_chan_get_buff(0, + [xport](double timeout) { return xport->get_recv_buff(timeout); }, false // flush ); // Create packet for packet handler to read vrt::if_packet_info_t packet_info; - packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; packet_info.num_payload_words32 = spp; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); - packet_info.has_tsf = true; - packet_info.tsf = 1; + packet_info.num_payload_bytes = packet_info.num_payload_words32 * sizeof(uint32_t); + packet_info.has_tsf = true; + packet_info.tsf = 1; std::vector<uint32_t> recv_data(spp, 0); xport->push_back_recv_packet(packet_info, recv_data); // Allocate buffer - std::vector<uint8_t> buffer(spp*bpi); + std::vector<uint8_t> buffer(spp * bpi); std::vector<void*> buffers; buffers.push_back(buffer.data()); // Run benchmark uhd::rx_metadata_t md; - const auto start_time = std::chrono::steady_clock::now(); + const auto start_time = std::chrono::steady_clock::now(); const size_t iterations = 1e7; for (size_t i = 0; i < iterations; i++) { @@ -90,29 +82,21 @@ void benchmark_recv_packet_handler( } const auto end_time = std::chrono::steady_clock::now(); - const std::chrono::duration<double> elapsed_time(end_time-start_time); + const std::chrono::duration<double> elapsed_time(end_time - start_time); const double time_per_packet = elapsed_time.count() / iterations; - std::cout << format << ": " - << time_per_packet / spp * 1e9 - << " ns/sample, " - << time_per_packet * 1e9 - << " ns/packet\n"; + std::cout << format << ": " << time_per_packet / spp * 1e9 << " ns/sample, " + << time_per_packet * 1e9 << " ns/packet\n"; } void benchmark_send_packet_handler( - const size_t spp, - const std::string& format, - bool use_time_spec -) { - const size_t bpi = uhd::convert::get_bytes_per_item(format); + const size_t spp, const std::string& format, bool use_time_spec) +{ + const size_t bpi = uhd::convert::get_bytes_per_item(format); const size_t frame_size = bpi * spp + DEVICE3_TX_MAX_HDR_LEN; - mock_zero_copy::sptr xport( - new mock_zero_copy( - vrt::if_packet_info_t::LINK_TYPE_CHDR, - frame_size, - frame_size)); + mock_zero_copy::sptr xport(new mock_zero_copy( + vrt::if_packet_info_t::LINK_TYPE_CHDR, frame_size, frame_size)); xport->set_reuse_send_memory(true); @@ -120,21 +104,18 @@ void benchmark_send_packet_handler( streamer.set_vrt_packer(&vrt::chdr::if_hdr_pack_be); uhd::convert::id_type id; - id.input_format = format; - id.num_inputs = 1; + id.input_format = format; + id.num_inputs = 1; id.output_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; streamer.set_converter(id); streamer.set_enable_trailer(false); streamer.set_xport_chan_get_buff( - 0, - [xport](double timeout) { - return xport->get_send_buff(timeout); - }); + 0, [xport](double timeout) { return xport->get_send_buff(timeout); }); // Allocate buffer - std::vector<uint8_t> buffer(spp*bpi); + std::vector<uint8_t> buffer(spp * bpi); std::vector<void*> buffers; buffers.push_back(buffer.data()); @@ -142,7 +123,7 @@ void benchmark_send_packet_handler( uhd::tx_metadata_t md; md.has_time_spec = use_time_spec; - const auto start_time = std::chrono::steady_clock::now(); + const auto start_time = std::chrono::steady_clock::now(); const size_t iterations = 1e7; for (size_t i = 0; i < iterations; i++) { @@ -153,44 +134,38 @@ void benchmark_send_packet_handler( } const auto end_time = std::chrono::steady_clock::now(); - const std::chrono::duration<double> elapsed_time(end_time-start_time); + const std::chrono::duration<double> elapsed_time(end_time - start_time); const double time_per_packet = elapsed_time.count() / iterations; - std::cout << format << ": " - << time_per_packet / spp * 1e9 - << " ns/sample, " - << time_per_packet * 1e9 - << " ns/packet\n"; + std::cout << format << ": " << time_per_packet / spp * 1e9 << " ns/sample, " + << time_per_packet * 1e9 << " ns/packet\n"; } -void benchmark_device3_rx_flow_ctrl( - bool send_flow_control_packet -) { +void benchmark_device3_rx_flow_ctrl(bool send_flow_control_packet) +{ // Arbitrary sizes constexpr uint32_t fc_window = 10000; - mock_zero_copy::sptr xport( - new mock_zero_copy( - vrt::if_packet_info_t::LINK_TYPE_CHDR)); + mock_zero_copy::sptr xport(new mock_zero_copy(vrt::if_packet_info_t::LINK_TYPE_CHDR)); xport->set_reuse_recv_memory(true); xport->set_reuse_send_memory(true); boost::shared_ptr<rx_fc_cache_t> fc_cache(new rx_fc_cache_t()); - fc_cache->to_host = uhd::ntohx<uint32_t>; + fc_cache->to_host = uhd::ntohx<uint32_t>; fc_cache->from_host = uhd::htonx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_be; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; - fc_cache->xport = xport; - fc_cache->interval = fc_window; + fc_cache->pack = vrt::chdr::if_hdr_pack_be; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; + fc_cache->xport = xport; + fc_cache->interval = fc_window; // Create data buffer to pass to flow control function. Number of payload // words is arbitrary, just has to fit in the buffer. vrt::if_packet_info_t packet_info; - packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; packet_info.num_payload_words32 = 100; - packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(uint32_t); - packet_info.has_tsf = false; + packet_info.num_payload_bytes = packet_info.num_payload_words32 * sizeof(uint32_t); + packet_info.has_tsf = false; std::vector<uint32_t> recv_data(packet_info.num_payload_words32, 0); xport->push_back_recv_packet(packet_info, recv_data); @@ -203,46 +178,44 @@ void benchmark_device3_rx_flow_ctrl( constexpr size_t iterations = 1e7; for (size_t i = 0; i < iterations; i++) { - fc_cache->total_bytes_consumed = send_flow_control_packet? fc_window:0; - fc_cache->last_byte_count = 0; + fc_cache->total_bytes_consumed = send_flow_control_packet ? fc_window : 0; + fc_cache->last_byte_count = 0; rx_flow_ctrl(fc_cache, recv_buffer); } const auto end_time = std::chrono::steady_clock::now(); - const std::chrono::duration<double> elapsed_time(end_time-start_time); + const std::chrono::duration<double> elapsed_time(end_time - start_time); - std::cout << elapsed_time.count() / iterations * 1e9 - << " ns per call\n"; + std::cout << elapsed_time.count() / iterations * 1e9 << " ns per call\n"; } -void benchmark_device3_handle_rx_flow_ctrl_ack() { +void benchmark_device3_handle_rx_flow_ctrl_ack() +{ // Arbitrary sizes constexpr uint32_t fc_window = 10000; - mock_zero_copy::sptr xport( - new mock_zero_copy( - vrt::if_packet_info_t::LINK_TYPE_CHDR)); + mock_zero_copy::sptr xport(new mock_zero_copy(vrt::if_packet_info_t::LINK_TYPE_CHDR)); xport->set_reuse_recv_memory(true); xport->set_reuse_send_memory(true); boost::shared_ptr<rx_fc_cache_t> fc_cache(new rx_fc_cache_t()); - fc_cache->to_host = uhd::ntohx<uint32_t>; - fc_cache->from_host = uhd::htonx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_be; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; - fc_cache->xport = xport; - fc_cache->interval = fc_window; + fc_cache->to_host = uhd::ntohx<uint32_t>; + fc_cache->from_host = uhd::htonx<uint32_t>; + fc_cache->pack = vrt::chdr::if_hdr_pack_be; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; + fc_cache->xport = xport; + fc_cache->interval = fc_window; fc_cache->total_bytes_consumed = 100; // Payload should contain packet count and byte count std::vector<uint32_t> payload_data; - payload_data.push_back(fc_cache->to_host(10)); // packet count + payload_data.push_back(fc_cache->to_host(10)); // packet count payload_data.push_back(fc_cache->to_host(100)); // byte count // Run benchmark - const auto start_time = std::chrono::steady_clock::now(); + const auto start_time = std::chrono::steady_clock::now(); constexpr size_t iterations = 1e7; for (size_t i = 0; i < iterations; i++) { @@ -250,75 +223,66 @@ void benchmark_device3_handle_rx_flow_ctrl_ack() { } const auto end_time = std::chrono::steady_clock::now(); - const std::chrono::duration<double> elapsed_time(end_time-start_time); + const std::chrono::duration<double> elapsed_time(end_time - start_time); - std::cout << elapsed_time.count() / iterations * 1e9 - << " ns per call\n"; + std::cout << elapsed_time.count() / iterations * 1e9 << " ns per call\n"; } -void benchmark_device3_tx_flow_ctrl( - bool send_flow_control_packet -) { +void benchmark_device3_tx_flow_ctrl(bool send_flow_control_packet) +{ // Arbitrary sizes constexpr uint32_t fc_window = 10000; - mock_zero_copy::sptr xport( - new mock_zero_copy( - vrt::if_packet_info_t::LINK_TYPE_CHDR)); + mock_zero_copy::sptr xport(new mock_zero_copy(vrt::if_packet_info_t::LINK_TYPE_CHDR)); xport->set_reuse_recv_memory(true); - boost::shared_ptr<tx_fc_cache_t> - fc_cache(new tx_fc_cache_t(fc_window)); + boost::shared_ptr<tx_fc_cache_t> fc_cache(new tx_fc_cache_t(fc_window)); - fc_cache->to_host = uhd::ntohx<uint32_t>; + fc_cache->to_host = uhd::ntohx<uint32_t>; fc_cache->from_host = uhd::htonx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_be; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; + fc_cache->pack = vrt::chdr::if_hdr_pack_be; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; xport->push_back_flow_ctrl_packet( - vrt::if_packet_info_t::PACKET_TYPE_FC, - 1 /*packet*/, - fc_window /*bytes*/); + vrt::if_packet_info_t::PACKET_TYPE_FC, 1 /*packet*/, fc_window /*bytes*/); // Run benchmark - const auto start_time = std::chrono::steady_clock::now(); - constexpr size_t iterations = 1e7; + const auto start_time = std::chrono::steady_clock::now(); + constexpr size_t iterations = 1e7; managed_send_buffer::sptr send_buffer = xport->get_send_buff(0.0); for (size_t i = 0; i < iterations; i++) { - fc_cache->byte_count = send_flow_control_packet? fc_window:0; + fc_cache->byte_count = send_flow_control_packet ? fc_window : 0; fc_cache->last_byte_ack = 0; tx_flow_ctrl(fc_cache, xport, send_buffer); } const auto end_time = std::chrono::steady_clock::now(); - const std::chrono::duration<double> elapsed_time(end_time-start_time); + const std::chrono::duration<double> elapsed_time(end_time - start_time); - std::cout << elapsed_time.count() / iterations * 1e9 - << " ns per call\n"; + std::cout << elapsed_time.count() / iterations * 1e9 << " ns per call\n"; } -void benchmark_device3_tx_flow_ctrl_ack() { +void benchmark_device3_tx_flow_ctrl_ack() +{ // Arbitrary sizes constexpr uint32_t fc_window = 10000; - mock_zero_copy::sptr xport( - new mock_zero_copy( - vrt::if_packet_info_t::LINK_TYPE_CHDR)); + mock_zero_copy::sptr xport(new mock_zero_copy(vrt::if_packet_info_t::LINK_TYPE_CHDR)); xport->set_reuse_send_memory(true); boost::shared_ptr<tx_fc_cache_t> fc_cache(new tx_fc_cache_t(fc_window)); - fc_cache->to_host = uhd::ntohx<uint32_t>; + fc_cache->to_host = uhd::ntohx<uint32_t>; fc_cache->from_host = uhd::htonx<uint32_t>; - fc_cache->pack = vrt::chdr::if_hdr_pack_be; - fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; + fc_cache->pack = vrt::chdr::if_hdr_pack_be; + fc_cache->unpack = vrt::chdr::if_hdr_unpack_be; // Run benchmark - const auto start_time = std::chrono::steady_clock::now(); + const auto start_time = std::chrono::steady_clock::now(); constexpr size_t iterations = 1e7; uhd::sid_t send_sid; @@ -330,18 +294,15 @@ void benchmark_device3_tx_flow_ctrl_ack() { } const auto end_time = std::chrono::steady_clock::now(); - const std::chrono::duration<double> elapsed_time(end_time-start_time); + const std::chrono::duration<double> elapsed_time(end_time - start_time); - std::cout << elapsed_time.count() / iterations * 1e9 - << " ns per call\n"; + std::cout << elapsed_time.count() / iterations * 1e9 << " ns per call\n"; } -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ; + desc.add_options()("help", "help message"); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -350,17 +311,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Print the help message if (vm.count("help")) { std::cout << boost::format("UHD Packet Handler Benchmark %s") % desc << std::endl; - std::cout << - " Benchmark of send and receive packet handlers and flow control\n" - " functions. All benchmarks use mock transport objects. No\n" - " parameters are needed to run this benchmark.\n" - << std::endl; + std::cout + << " Benchmark of send and receive packet handlers and flow control\n" + " functions. All benchmarks use mock transport objects. No\n" + " parameters are needed to run this benchmark.\n" + << std::endl; return EXIT_FAILURE; } uhd::set_thread_priority_safe(); - const char* formats[] = {"sc16", "fc32", "fc64" }; + const char* formats[] = {"sc16", "fc32", "fc64"}; constexpr size_t rx_spp = 2000; constexpr size_t tx_spp = 1000; diff --git a/host/tests/paths_test.cpp b/host/tests/paths_test.cpp index 0ccebd333..ef10414c7 100644 --- a/host/tests/paths_test.cpp +++ b/host/tests/paths_test.cpp @@ -8,12 +8,13 @@ #include <uhd/exception.hpp> #include <uhd/utils/paths.hpp> #include <uhdlib/utils/paths.hpp> -#include <boost/test/unit_test.hpp> #include <boost/filesystem/operations.hpp> -#include <vector> +#include <boost/test/unit_test.hpp> #include <iostream> +#include <vector> -BOOST_AUTO_TEST_CASE(test_paths_expandvars) { +BOOST_AUTO_TEST_CASE(test_paths_expandvars) +{ #ifdef UHD_PLATFORM_WIN32 const std::string path_to_expand("\%programdata%/uhd/uhd.conf"); #else @@ -21,8 +22,8 @@ BOOST_AUTO_TEST_CASE(test_paths_expandvars) { #endif const std::string expanded_path = uhd::path_expandvars(path_to_expand); - std::cout << "Expanded path: " << path_to_expand << " -> " - << expanded_path << std::endl; + std::cout << "Expanded path: " << path_to_expand << " -> " << expanded_path + << std::endl; BOOST_CHECK(path_to_expand != expanded_path); #ifdef UHD_PLATFORM_WIN32 @@ -35,13 +36,14 @@ BOOST_AUTO_TEST_CASE(test_paths_expandvars) { } -BOOST_AUTO_TEST_CASE(test_get_paths) { +BOOST_AUTO_TEST_CASE(test_get_paths) +{ using namespace uhd; const std::string tmp_path = get_tmp_path(); const std::string app_path = get_app_path(); const std::string pkg_path = get_pkg_path(); - const auto module_paths = get_module_paths(); + const auto module_paths = get_module_paths(); std::cout << "tmp_path: " << tmp_path << std::endl; std::cout << "app_path: " << app_path << std::endl; @@ -51,22 +53,14 @@ BOOST_AUTO_TEST_CASE(test_get_paths) { } const std::string images_dir_search_path = ""; - const std::string images_dir = get_images_dir(images_dir_search_path); + const std::string images_dir = get_images_dir(images_dir_search_path); BOOST_REQUIRE_THROW( - find_image_path("this_device_does_not_exist.bit", ""), - uhd::io_error - ); + find_image_path("this_device_does_not_exist.bit", ""), uhd::io_error); - const std::string utility_path = find_utility( - "uhd_images_downloader" - ); + const std::string utility_path = find_utility("uhd_images_downloader"); std::cout << "utility_path: " << utility_path << std::endl; - const std::string utility_error = print_utility_error( - "uhd_images_downloader", - "--help" - ); + const std::string utility_error = + print_utility_error("uhd_images_downloader", "--help"); std::cout << "utility_error: " << tmp_path << std::endl; - } - diff --git a/host/tests/property_test.cpp b/host/tests/property_test.cpp index 3daeed510..b2086f288 100644 --- a/host/tests/property_test.cpp +++ b/host/tests/property_test.cpp @@ -5,22 +5,26 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/property_tree.hpp> #include <boost/bind.hpp> +#include <boost/test/unit_test.hpp> #include <exception> #include <iostream> -struct coercer_type{ - int doit(int x){ +struct coercer_type +{ + int doit(int x) + { return x & ~0x3; } }; -struct setter_type{ +struct setter_type +{ setter_type() : _count(0), _x(0) {} - void doit(int x){ + void doit(int x) + { _count++; _x = x; } @@ -29,10 +33,12 @@ struct setter_type{ int _x; }; -struct getter_type{ +struct getter_type +{ getter_type() : _count(0), _x(0) {} - int doit(void){ + int doit(void) + { _count++; return _x; } @@ -41,9 +47,10 @@ struct getter_type{ int _x; }; -BOOST_AUTO_TEST_CASE(test_prop_simple){ +BOOST_AUTO_TEST_CASE(test_prop_simple) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/"); + uhd::property<int>& prop = tree->create<int>("/"); BOOST_CHECK(prop.empty()); prop.set(0); @@ -55,9 +62,10 @@ BOOST_AUTO_TEST_CASE(test_prop_simple){ BOOST_CHECK_EQUAL(prop.get(), 34); } -BOOST_AUTO_TEST_CASE(test_prop_with_desired_subscriber){ +BOOST_AUTO_TEST_CASE(test_prop_with_desired_subscriber) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/"); + uhd::property<int>& prop = tree->create<int>("/"); setter_type setter; prop.add_desired_subscriber(boost::bind(&setter_type::doit, &setter, _1)); @@ -73,9 +81,10 @@ BOOST_AUTO_TEST_CASE(test_prop_with_desired_subscriber){ BOOST_CHECK_EQUAL(setter._x, 34); } -BOOST_AUTO_TEST_CASE(test_prop_with_coerced_subscriber){ +BOOST_AUTO_TEST_CASE(test_prop_with_coerced_subscriber) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/"); + uhd::property<int>& prop = tree->create<int>("/"); setter_type setter; prop.add_coerced_subscriber(boost::bind(&setter_type::doit, &setter, _1)); @@ -91,9 +100,10 @@ BOOST_AUTO_TEST_CASE(test_prop_with_coerced_subscriber){ BOOST_CHECK_EQUAL(setter._x, 34); } -BOOST_AUTO_TEST_CASE(test_prop_manual_coercion){ +BOOST_AUTO_TEST_CASE(test_prop_manual_coercion) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/", uhd::property_tree::MANUAL_COERCE); + uhd::property<int>& prop = tree->create<int>("/", uhd::property_tree::MANUAL_COERCE); setter_type dsetter, csetter; prop.add_desired_subscriber(boost::bind(&setter_type::doit, &dsetter, _1)); @@ -114,9 +124,10 @@ BOOST_AUTO_TEST_CASE(test_prop_manual_coercion){ BOOST_CHECK_EQUAL(csetter._x, 34); } -BOOST_AUTO_TEST_CASE(test_prop_with_publisher){ +BOOST_AUTO_TEST_CASE(test_prop_with_publisher) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/"); + uhd::property<int>& prop = tree->create<int>("/"); BOOST_CHECK(prop.empty()); getter_type getter; @@ -124,17 +135,18 @@ BOOST_AUTO_TEST_CASE(test_prop_with_publisher){ BOOST_CHECK(not prop.empty()); getter._x = 42; - prop.set(0); //should not change + prop.set(0); // should not change BOOST_CHECK_EQUAL(prop.get(), 42); getter._x = 34; - prop.set(0); //should not change + prop.set(0); // should not change BOOST_CHECK_EQUAL(prop.get(), 34); } -BOOST_AUTO_TEST_CASE(test_prop_with_publisher_and_subscriber){ +BOOST_AUTO_TEST_CASE(test_prop_with_publisher_and_subscriber) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/"); + uhd::property<int>& prop = tree->create<int>("/"); getter_type getter; prop.set_publisher(boost::bind(&getter_type::doit, &getter)); @@ -153,9 +165,10 @@ BOOST_AUTO_TEST_CASE(test_prop_with_publisher_and_subscriber){ BOOST_CHECK_EQUAL(setter._x, 1); } -BOOST_AUTO_TEST_CASE(test_prop_with_coercion){ +BOOST_AUTO_TEST_CASE(test_prop_with_coercion) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); - uhd::property<int> &prop = tree->create<int>("/"); + uhd::property<int>& prop = tree->create<int>("/"); setter_type setter; prop.add_coerced_subscriber(boost::bind(&setter_type::doit, &setter, _1)); @@ -172,7 +185,8 @@ BOOST_AUTO_TEST_CASE(test_prop_with_coercion){ BOOST_CHECK_EQUAL(setter._x, 32); } -BOOST_AUTO_TEST_CASE(test_prop_tree){ +BOOST_AUTO_TEST_CASE(test_prop_tree) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); tree->create<int>("/test/prop0"); @@ -196,42 +210,43 @@ BOOST_AUTO_TEST_CASE(test_prop_tree){ tree->remove("/test"); BOOST_CHECK(not tree->exists("/test/prop0")); BOOST_CHECK(not tree->exists("/test/prop1")); - } -BOOST_AUTO_TEST_CASE(test_prop_subtree){ +BOOST_AUTO_TEST_CASE(test_prop_subtree) +{ uhd::property_tree::sptr tree = uhd::property_tree::make(); tree->create<int>("/subdir1/subdir2"); - uhd::property_tree::sptr subtree1 = tree->subtree("/"); - const std::vector<std::string> tree_dirs1 = tree->list("/"); + uhd::property_tree::sptr subtree1 = tree->subtree("/"); + const std::vector<std::string> tree_dirs1 = tree->list("/"); const std::vector<std::string> subtree1_dirs = subtree1->list(""); - BOOST_CHECK_EQUAL_COLLECTIONS(tree_dirs1.begin(), tree_dirs1.end(), subtree1_dirs.begin(), subtree1_dirs.end()); + BOOST_CHECK_EQUAL_COLLECTIONS( + tree_dirs1.begin(), tree_dirs1.end(), subtree1_dirs.begin(), subtree1_dirs.end()); - uhd::property_tree::sptr subtree2 = subtree1->subtree("subdir1"); - const std::vector<std::string> tree_dirs2 = tree->list("/subdir1"); + uhd::property_tree::sptr subtree2 = subtree1->subtree("subdir1"); + const std::vector<std::string> tree_dirs2 = tree->list("/subdir1"); const std::vector<std::string> subtree2_dirs = subtree2->list(""); - BOOST_CHECK_EQUAL_COLLECTIONS(tree_dirs2.begin(), tree_dirs2.end(), subtree2_dirs.begin(), subtree2_dirs.end()); - + BOOST_CHECK_EQUAL_COLLECTIONS( + tree_dirs2.begin(), tree_dirs2.end(), subtree2_dirs.begin(), subtree2_dirs.end()); } BOOST_AUTO_TEST_CASE(test_prop_operators) { uhd::fs_path path1 = "/root/"; - path1 = path1 / "leaf"; + path1 = path1 / "leaf"; BOOST_CHECK_EQUAL(path1, "/root/leaf"); uhd::fs_path path2 = "/root"; - path2 = path2 / "leaf"; + path2 = path2 / "leaf"; BOOST_CHECK_EQUAL(path2, "/root/leaf"); uhd::fs_path path3 = "/root/"; - path3 = path3 / "/leaf/"; + path3 = path3 / "/leaf/"; BOOST_CHECK_EQUAL(path3, "/root/leaf/"); uhd::fs_path path4 = "/root/"; - size_t x = 2; - path4 = path4 / x; + size_t x = 2; + path4 = path4 / x; BOOST_CHECK_EQUAL(path4, "/root/2"); } diff --git a/host/tests/ranges_test.cpp b/host/tests/ranges_test.cpp index fd6336a55..223560289 100644 --- a/host/tests/ranges_test.cpp +++ b/host/tests/ranges_test.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/types/ranges.hpp> +#include <boost/test/unit_test.hpp> #include <iostream> using namespace uhd; @@ -14,7 +14,8 @@ using namespace uhd; static const double tolerance = 0.001; // % -BOOST_AUTO_TEST_CASE(test_ranges_bounds){ +BOOST_AUTO_TEST_CASE(test_ranges_bounds) +{ meta_range_t mr; mr.push_back(range_t(-1.0, +1.0, 0.1)); BOOST_CHECK_CLOSE(mr.start(), -1.0, tolerance); @@ -33,7 +34,8 @@ BOOST_AUTO_TEST_CASE(test_ranges_bounds){ BOOST_CHECK_CLOSE(mr[0].step(), 0.1, tolerance); } -BOOST_AUTO_TEST_CASE(test_ranges_clip){ +BOOST_AUTO_TEST_CASE(test_ranges_clip) +{ meta_range_t mr; mr.push_back(range_t(-1.0, +1.0, 0.1)); mr.push_back(range_t(40.0, 60.0, 1.0)); @@ -47,7 +49,8 @@ BOOST_AUTO_TEST_CASE(test_ranges_clip){ BOOST_CHECK_CLOSE(mr.clip(50.9, true), 51.0, tolerance); } -BOOST_AUTO_TEST_CASE(test_meta_range_t_ctor){ +BOOST_AUTO_TEST_CASE(test_meta_range_t_ctor) +{ meta_range_t mr1(0.0, 10.0, 1.0); BOOST_CHECK_CLOSE(mr1.clip(5.0), 5.0, tolerance); BOOST_CHECK_CLOSE(mr1.clip(11.0), 10.0, tolerance); @@ -64,7 +67,8 @@ BOOST_AUTO_TEST_CASE(test_meta_range_t_ctor){ BOOST_CHECK_CLOSE(mr3.clip(5.1, true), 5.1, tolerance); } -BOOST_AUTO_TEST_CASE(test_ranges_clip2){ +BOOST_AUTO_TEST_CASE(test_ranges_clip2) +{ meta_range_t mr; mr.push_back(range_t(1.)); mr.push_back(range_t(2.)); @@ -77,7 +81,8 @@ BOOST_AUTO_TEST_CASE(test_ranges_clip2){ BOOST_CHECK_CLOSE(mr.clip(4., true), 3., tolerance); } -BOOST_AUTO_TEST_CASE(test_ranges_compare){ +BOOST_AUTO_TEST_CASE(test_ranges_compare) +{ range_t range(1); range_t n_range(1); range_t d_range(2); diff --git a/host/tests/rate_node_test.cpp b/host/tests/rate_node_test.cpp index f7e1bf30b..85502c325 100644 --- a/host/tests/rate_node_test.cpp +++ b/host/tests/rate_node_test.cpp @@ -18,7 +18,7 @@ class rate_aware_node : public test_node, public rate_node_ctrl public: typedef boost::shared_ptr<rate_aware_node> sptr; - rate_aware_node(const std::string &test_id) : test_node(test_id) {}; + rate_aware_node(const std::string& test_id) : test_node(test_id){}; }; /* class rate_aware_node */ @@ -28,10 +28,17 @@ class rate_setting_node : public test_node, public rate_node_ctrl public: typedef boost::shared_ptr<rate_setting_node> sptr; - rate_setting_node(const std::string &test_id, double samp_rate) : test_node(test_id), _samp_rate(samp_rate) {}; + rate_setting_node(const std::string& test_id, double samp_rate) + : test_node(test_id), _samp_rate(samp_rate){}; - double get_input_samp_rate(size_t) { return _samp_rate; }; - double get_output_samp_rate(size_t) { return _samp_rate; }; + double get_input_samp_rate(size_t) + { + return _samp_rate; + }; + double get_output_samp_rate(size_t) + { + return _samp_rate; + }; private: double _samp_rate; @@ -39,7 +46,8 @@ private: }; /* class rate_setting_node */ #define MAKE_RATE_NODE(name) rate_aware_node::sptr name(new rate_aware_node(#name)); -#define MAKE_RATE_SETTING_NODE(name, rate) rate_setting_node::sptr name(new rate_setting_node(#name, rate)); +#define MAKE_RATE_SETTING_NODE(name, rate) \ + rate_setting_node::sptr name(new rate_setting_node(#name, rate)); BOOST_AUTO_TEST_CASE(test_simplest_downstream_search) { @@ -126,4 +134,3 @@ BOOST_AUTO_TEST_CASE(test_skip_upstream_search) double result_rate = node_C->get_output_samp_rate(); BOOST_CHECK_EQUAL(result_rate, test_rate); } - diff --git a/host/tests/sensors_test.cpp b/host/tests/sensors_test.cpp index 2136ca13b..925f1a711 100644 --- a/host/tests/sensors_test.cpp +++ b/host/tests/sensors_test.cpp @@ -4,20 +4,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/types/sensors.hpp> +#include <boost/test/unit_test.hpp> #include <map> #include <string> using uhd::sensor_value_t; -BOOST_AUTO_TEST_CASE(test_sensor_bool) { - auto sensor_bool = sensor_value_t( - "bool_sensor", - true, - "true_unit", - "false_unit" - ); +BOOST_AUTO_TEST_CASE(test_sensor_bool) +{ + auto sensor_bool = sensor_value_t("bool_sensor", true, "true_unit", "false_unit"); BOOST_CHECK(sensor_bool.to_bool()); BOOST_CHECK_EQUAL(sensor_bool.unit, "true_unit"); @@ -34,11 +30,12 @@ BOOST_AUTO_TEST_CASE(test_sensor_bool) { } -BOOST_AUTO_TEST_CASE(test_sensor_real) { - const double sens_val = 2.25; +BOOST_AUTO_TEST_CASE(test_sensor_real) +{ + const double sens_val = 2.25; const std::string sens_units = "floats"; - const std::string sens_name = "real_sensor"; - auto sensor_real = sensor_value_t(sens_name, sens_val, sens_units); + const std::string sens_name = "real_sensor"; + auto sensor_real = sensor_value_t(sens_name, sens_val, sens_units); BOOST_CHECK_EQUAL(sensor_real.to_real(), sens_val); BOOST_CHECK_EQUAL(sensor_real.unit, sens_units); @@ -54,11 +51,12 @@ BOOST_AUTO_TEST_CASE(test_sensor_real) { BOOST_CHECK_EQUAL(sensor_real2.unit, sens_units); } -BOOST_AUTO_TEST_CASE(test_sensor_int) { - const int sens_val = 5; +BOOST_AUTO_TEST_CASE(test_sensor_int) +{ + const int sens_val = 5; const std::string sens_units = "ints"; - const std::string sens_name = "int_sensor"; - auto sensor_int = sensor_value_t(sens_name, sens_val, sens_units); + const std::string sens_name = "int_sensor"; + auto sensor_int = sensor_value_t(sens_name, sens_val, sens_units); BOOST_CHECK_EQUAL(sensor_int.to_int(), sens_val); BOOST_CHECK_EQUAL(sensor_int.unit, sens_units); @@ -74,11 +72,12 @@ BOOST_AUTO_TEST_CASE(test_sensor_int) { BOOST_CHECK_EQUAL(sensor_int2.unit, sens_units); } -BOOST_AUTO_TEST_CASE(test_sensor_string) { - const std::string sens_val = "foo"; +BOOST_AUTO_TEST_CASE(test_sensor_string) +{ + const std::string sens_val = "foo"; const std::string sens_units = "strings"; - const std::string sens_name = "str_sensor"; - auto sensor_str = sensor_value_t(sens_name, sens_val, sens_units); + const std::string sens_name = "str_sensor"; + auto sensor_str = sensor_value_t(sens_name, sens_val, sens_units); BOOST_CHECK_EQUAL(sensor_str.value, sens_val); BOOST_CHECK_EQUAL(sensor_str.unit, sens_units); @@ -97,6 +96,4 @@ BOOST_AUTO_TEST_CASE(test_sensor_string) { BOOST_CHECK_EQUAL(sensor_str2.value, sensor_str3.value); BOOST_CHECK_EQUAL(sensor_str2.unit, sensor_str3.unit); BOOST_CHECK_EQUAL(sensor_str2.type, sensor_str3.type); - } - diff --git a/host/tests/sid_t_test.cpp b/host/tests/sid_t_test.cpp index 1e643e059..85d33c45e 100644 --- a/host/tests/sid_t_test.cpp +++ b/host/tests/sid_t_test.cpp @@ -5,15 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/exception.hpp> +#include <uhd/types/sid.hpp> +#include <boost/test/unit_test.hpp> #include <iostream> #include <sstream> -#include <boost/test/unit_test.hpp> -#include <uhd/types/sid.hpp> -#include <uhd/exception.hpp> using uhd::sid_t; -BOOST_AUTO_TEST_CASE(test_sid_t) { +BOOST_AUTO_TEST_CASE(test_sid_t) +{ uint32_t sid_value = 0x01020310; sid_t sid(sid_value); @@ -29,7 +30,7 @@ BOOST_AUTO_TEST_CASE(test_sid_t) { BOOST_CHECK_EQUAL(sid == sid, true); BOOST_CHECK_EQUAL(sid == sid_value, true); - uint32_t check_sid_val = (uint32_t) sid; + uint32_t check_sid_val = (uint32_t)sid; BOOST_CHECK_EQUAL(check_sid_val, sid_value); std::stringstream ss_dec; @@ -46,20 +47,21 @@ BOOST_AUTO_TEST_CASE(test_sid_t) { BOOST_CHECK_EQUAL(empty_sid.to_pp_string_hex(), "xx:xx>xx:xx"); BOOST_CHECK_EQUAL(empty_sid == sid, false); BOOST_CHECK_EQUAL(empty_sid == sid_value, false); - BOOST_CHECK_EQUAL((bool) empty_sid, false); + BOOST_CHECK_EQUAL((bool)empty_sid, false); empty_sid = sid_value; // No longer empty BOOST_CHECK_EQUAL(empty_sid.is_set(), true); BOOST_CHECK_EQUAL(empty_sid == sid, true); } -BOOST_AUTO_TEST_CASE(test_sid_t_set) { +BOOST_AUTO_TEST_CASE(test_sid_t_set) +{ uint32_t sid_value = 0x0; sid_t sid(sid_value); sid.set(0x01020304); BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x01020304); - BOOST_CHECK_EQUAL(sid.get_src_addr(),(uint32_t)0x01); + BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x01); BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x02); BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x03); BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x04); @@ -117,7 +119,8 @@ BOOST_AUTO_TEST_CASE(test_sid_t_set) { BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0cbc0a0b); } -BOOST_AUTO_TEST_CASE(test_sid_t_from_str) { +BOOST_AUTO_TEST_CASE(test_sid_t_from_str) +{ sid_t sid("1.2>3.4"); BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)1); BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)2); diff --git a/host/tests/soft_reg_test.cpp b/host/tests/soft_reg_test.cpp index 8e53c61ca..2c1766cfe 100644 --- a/host/tests/soft_reg_test.cpp +++ b/host/tests/soft_reg_test.cpp @@ -9,21 +9,22 @@ using namespace uhd; -BOOST_AUTO_TEST_CASE(test_soft_reg_field) { +BOOST_AUTO_TEST_CASE(test_soft_reg_field) +{ UHD_DEFINE_SOFT_REG_FIELD(test_reg1, /* width */ 1, /* shift */ 0); BOOST_CHECK_EQUAL(soft_reg_field::width(test_reg1), 1); BOOST_CHECK_EQUAL(soft_reg_field::shift(test_reg1), 0); - BOOST_CHECK_EQUAL(soft_reg_field::mask<uint32_t>(test_reg1), 1<<0); + BOOST_CHECK_EQUAL(soft_reg_field::mask<uint32_t>(test_reg1), 1 << 0); UHD_DEFINE_SOFT_REG_FIELD(test_reg2, /* width */ 5, /* shift */ 4); BOOST_CHECK_EQUAL(soft_reg_field::width(test_reg2), 5); BOOST_CHECK_EQUAL(soft_reg_field::shift(test_reg2), 4); - BOOST_CHECK_EQUAL(soft_reg_field::mask<uint32_t>(test_reg2), 0x1F<<4); + BOOST_CHECK_EQUAL(soft_reg_field::mask<uint32_t>(test_reg2), 0x1F << 4); UHD_DEFINE_SOFT_REG_FIELD(test_reg3, /* width */ 9, /* shift */ 0); BOOST_CHECK_EQUAL(soft_reg_field::width(test_reg3), 9); BOOST_CHECK_EQUAL(soft_reg_field::shift(test_reg3), 0); - BOOST_CHECK_EQUAL(soft_reg_field::mask<uint8_t>(test_reg3), 0xFF); + BOOST_CHECK_EQUAL(soft_reg_field::mask<uint8_t>(test_reg3), 0xFF); // This one is platform dependent: UHD_DEFINE_SOFT_REG_FIELD(test_reg4, /* width */ 33, /* shift */ 0); diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp index 705fd4f83..3c185d21a 100644 --- a/host/tests/sph_recv_test.cpp +++ b/host/tests/sph_recv_test.cpp @@ -5,14 +5,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> -#include "../lib/transport/super_recv_packet_handler.hpp" #include "../common/mock_zero_copy.hpp" -#include <boost/shared_array.hpp> +#include "../lib/transport/super_recv_packet_handler.hpp" #include <boost/bind.hpp> +#include <boost/shared_array.hpp> +#include <boost/test/unit_test.hpp> #include <complex> -#include <vector> #include <list> +#include <vector> using namespace uhd::transport; @@ -22,797 +22,775 @@ using namespace uhd::transport; /*********************************************************************** * A dummy overflow handler for testing **********************************************************************/ -struct overflow_handler_type{ - overflow_handler_type(void){ +struct overflow_handler_type +{ + overflow_handler_type(void) + { num_overflow = 0; } - void handle(void){ + void handle(void) + { num_overflow++; } size_t num_overflow; }; //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xport.push_back_recv_packet(ifpi, data); ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); } - //create the super receive packet handler + // create the super receive packet handler uhd::transport::sph::recv_packet_handler handler(1); handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); handler.set_xport_chan_get_buff( - 0, - [&xport](double timeout) { - return xport.get_recv_buff(timeout); - }); + 0, [&xport](double timeout) { return xport.get_recv_buff(timeout); }); handler.set_converter(id); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > buff(20); + std::vector<std::complex<float>> buff(20); uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); + size_t num_samps_ret = + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); + BOOST_CHECK_TS_CLOSE( + metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, 10 + i % 10); num_accum_samps += num_samps_ret; } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing + // simulate the transport failing xport.set_simulate_io_error(true); - BOOST_REQUIRE_THROW(handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; - if (i != NUM_PKTS_TO_TEST/2){ //simulate a lost packet + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; + if (i != NUM_PKTS_TO_TEST / 2) { // simulate a lost packet std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xport.push_back_recv_packet(ifpi, data); } ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(1); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); handler.set_xport_chan_get_buff( - 0, - [&xport](double timeout) { - return xport.get_recv_buff(timeout); - } - ); + 0, [&xport](double timeout) { return xport.get_recv_buff(timeout); }); handler.set_converter(id); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > buff(20); + std::vector<std::complex<float>> buff(20); uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); - if (i == NUM_PKTS_TO_TEST/2){ - //must get the soft overflow here + size_t num_samps_ret = + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); + if (i == NUM_PKTS_TO_TEST / 2) { + // must get the soft overflow here BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); BOOST_REQUIRE(metadata.out_of_sequence == true); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - num_accum_samps += 10 + i%10; - } - else{ + BOOST_CHECK_TS_CLOSE(metadata.time_spec, + uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + num_accum_samps += 10 + i % 10; + } else { BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, + uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, 10 + i % 10); num_accum_samps += num_samps_ret; } } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing + // simulate the transport failing xport.set_simulate_io_error(true); - BOOST_REQUIRE_THROW(handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; - ifpi.num_payload_words32 = 10 + i%10; + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.num_payload_words32 = 10 + i % 10; std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xport.push_back_recv_packet(ifpi, data); ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); - //simulate overflow - if (i == NUM_PKTS_TO_TEST/2){ - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; + // simulate overflow + if (i == NUM_PKTS_TO_TEST / 2) { + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; ifpi.num_payload_words32 = 1; xport.push_back_inline_message_packet( - ifpi, - uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); + ifpi, uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); } } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(1); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); handler.set_xport_chan_get_buff( - 0, - [&xport](double timeout) { - return xport.get_recv_buff(timeout); - } - ); + 0, [&xport](double timeout) { return xport.get_recv_buff(timeout); }); handler.set_converter(id); - //create an overflow handler + // create an overflow handler overflow_handler_type overflow_handler; - handler.set_overflow_handler(0, boost::bind(&overflow_handler_type::handle, &overflow_handler)); + handler.set_overflow_handler( + 0, boost::bind(&overflow_handler_type::handle, &overflow_handler)); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::vector<std::complex<float> > buff(20); + std::vector<std::complex<float>> buff(20); uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); + size_t num_samps_ret = + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); + BOOST_CHECK_TS_CLOSE( + metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, 10 + i % 10); num_accum_samps += num_samps_ret; - if (i == NUM_PKTS_TO_TEST/2){ - handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); + if (i == NUM_PKTS_TO_TEST / 2) { + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); std::cout << "metadata.error_code " << metadata.error_code << std::endl; BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, + uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(overflow_handler.num_overflow, size_t(1)); } } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - &buff.front(), buff.size(), metadata, 1.0, true - ); + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing + // simulate the transport failing xport.set_simulate_io_error(true); - BOOST_REQUIRE_THROW(handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; - static const size_t NUM_PKTS_TO_TEST = 30; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; + static const size_t NUM_PKTS_TO_TEST = 30; static const size_t NUM_SAMPS_PER_BUFF = 20; - static const size_t NCHANNELS = 4; + static const size_t NCHANNELS = 4; std::vector<mock_zero_copy::sptr> xports; for (size_t i = 0; i < NCHANNELS; i++) { - xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + xports.push_back( + boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); } - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; + for (size_t ch = 0; ch < NCHANNELS; ch++) { std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(NCHANNELS); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - for (size_t ch = 0; ch < NCHANNELS; ch++){ + for (size_t ch = 0; ch < NCHANNELS; ch++) { mock_zero_copy::sptr xport = xports[ch]; handler.set_xport_chan_get_buff( - ch, - [xport](double timeout) { - return xport->get_recv_buff(timeout); - } - ); + ch, [xport](double timeout) { return xport->get_recv_buff(timeout); }); } handler.set_converter(id); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; - std::vector<std::complex<float> *> buffs(NCHANNELS); - for (size_t ch = 0; ch < NCHANNELS; ch++){ - buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; + std::complex<float> mem[NUM_SAMPS_PER_BUFF * NCHANNELS]; + std::vector<std::complex<float>*> buffs(NCHANNELS); + for (size_t ch = 0; ch < NCHANNELS; ch++) { + buffs[ch] = &mem[ch * NUM_SAMPS_PER_BUFF]; } uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + size_t num_samps_ret = + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); + BOOST_CHECK_TS_CLOSE( + metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, 10 + i % 10); num_accum_samps += num_samps_ret; } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // simulate the transport failing + for (size_t ch = 0; ch < NCHANNELS; ch++) { xports[ch]->set_simulate_io_error(true); } - BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; - static const size_t NUM_PKTS_TO_TEST = 30; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; + static const size_t NUM_PKTS_TO_TEST = 30; static const size_t NUM_SAMPS_PER_BUFF = 20; - static const size_t NCHANNELS = 4; + static const size_t NCHANNELS = 4; std::vector<mock_zero_copy::sptr> xports; for (size_t i = 0; i < NCHANNELS; i++) { - xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + xports.push_back( + boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); } - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; - for (size_t ch = 0; ch < NCHANNELS; ch++){ - if (i == NUM_PKTS_TO_TEST/2 and ch == 2){ - continue; //simulates a lost packet + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; + for (size_t ch = 0; ch < NCHANNELS; ch++) { + if (i == NUM_PKTS_TO_TEST / 2 and ch == 2) { + continue; // simulates a lost packet } std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(NCHANNELS); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - for (size_t ch = 0; ch < NCHANNELS; ch++){ + for (size_t ch = 0; ch < NCHANNELS; ch++) { mock_zero_copy::sptr xport = xports[ch]; handler.set_xport_chan_get_buff( - ch, - [xport](double timeout) { - return xport->get_recv_buff(timeout); - } - ); + ch, [xport](double timeout) { return xport->get_recv_buff(timeout); }); } handler.set_converter(id); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; - std::vector<std::complex<float> *> buffs(NCHANNELS); - for (size_t ch = 0; ch < NCHANNELS; ch++){ - buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; + std::complex<float> mem[NUM_SAMPS_PER_BUFF * NCHANNELS]; + std::vector<std::complex<float>*> buffs(NCHANNELS); + for (size_t ch = 0; ch < NCHANNELS; ch++) { + buffs[ch] = &mem[ch * NUM_SAMPS_PER_BUFF]; } uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); - if (i == NUM_PKTS_TO_TEST/2){ - //must get the soft overflow here + size_t num_samps_ret = + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); + if (i == NUM_PKTS_TO_TEST / 2) { + // must get the soft overflow here BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); BOOST_REQUIRE(metadata.out_of_sequence == true); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - num_accum_samps += 10 + i%10; - } - else{ + BOOST_CHECK_TS_CLOSE(metadata.time_spec, + uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + num_accum_samps += 10 + i % 10; + } else { BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); + BOOST_CHECK_TS_CLOSE(metadata.time_spec, + uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, 10 + i % 10); num_accum_samps += num_samps_ret; } } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // simulate the transport failing + for (size_t ch = 0; ch < NCHANNELS; ch++) { xports[ch]->set_simulate_io_error(true); } - BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; - static const size_t NUM_PKTS_TO_TEST = 30; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; + static const size_t NUM_PKTS_TO_TEST = 30; static const size_t NUM_SAMPS_PER_BUFF = 20; - static const size_t NCHANNELS = 4; + static const size_t NCHANNELS = 4; std::vector<mock_zero_copy::sptr> xports; for (size_t i = 0; i < NCHANNELS; i++) { - xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + xports.push_back( + boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); } - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; + for (size_t ch = 0; ch < NCHANNELS; ch++) { std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); - if (i == NUM_PKTS_TO_TEST/2){ - ifpi.tsf = 0; //simulate the user changing the time + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); + if (i == NUM_PKTS_TO_TEST / 2) { + ifpi.tsf = 0; // simulate the user changing the time } } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(NCHANNELS); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - for (size_t ch = 0; ch < NCHANNELS; ch++){ + for (size_t ch = 0; ch < NCHANNELS; ch++) { mock_zero_copy::sptr xport = xports[ch]; handler.set_xport_chan_get_buff( - ch, - [xport](double timeout) { - return xport->get_recv_buff(timeout); - } - ); + ch, [xport](double timeout) { return xport->get_recv_buff(timeout); }); } handler.set_converter(id); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; - std::vector<std::complex<float> *> buffs(NCHANNELS); - for (size_t ch = 0; ch < NCHANNELS; ch++){ - buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; + std::complex<float> mem[NUM_SAMPS_PER_BUFF * NCHANNELS]; + std::vector<std::complex<float>*> buffs(NCHANNELS); + for (size_t ch = 0; ch < NCHANNELS; ch++) { + buffs[ch] = &mem[ch * NUM_SAMPS_PER_BUFF]; } uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + size_t num_samps_ret = + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10); + BOOST_CHECK_TS_CLOSE( + metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, 10 + i % 10); num_accum_samps += num_samps_ret; - if (i == NUM_PKTS_TO_TEST/2){ - num_accum_samps = 0; //simulate the user changing the time + if (i == NUM_PKTS_TO_TEST / 2) { + num_accum_samps = 0; // simulate the user changing the time } } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // simulate the transport failing + for (size_t ch = 0; ch < NCHANNELS; ch++) { xports[ch]->set_simulate_io_error(true); } - BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_exception){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_exception) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; - static const size_t NUM_PKTS_TO_TEST = 30; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; + static const size_t NUM_PKTS_TO_TEST = 30; static const size_t NUM_SAMPS_PER_BUFF = 20; - static const size_t NCHANNELS = 4; + static const size_t NCHANNELS = 4; std::vector<mock_zero_copy::sptr> xports; for (size_t i = 0; i < NCHANNELS; i++) { - xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + xports.push_back( + boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); } - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; + for (size_t ch = 0; ch < NCHANNELS; ch++) { std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); - if (i == NUM_PKTS_TO_TEST/2){ - ifpi.tsf = 0; //simulate the user changing the time + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); + if (i == NUM_PKTS_TO_TEST / 2) { + ifpi.tsf = 0; // simulate the user changing the time } } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(NCHANNELS); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - for (size_t ch = 0; ch < NCHANNELS; ch++){ + for (size_t ch = 0; ch < NCHANNELS; ch++) { mock_zero_copy::sptr xport = xports[ch]; handler.set_xport_chan_get_buff( - ch, - [xport](double timeout) { - return xport->get_recv_buff(timeout); - } - ); + ch, [xport](double timeout) { return xport->get_recv_buff(timeout); }); } handler.set_converter(id); - std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; - std::vector<std::complex<float> *> buffs(NCHANNELS); - for (size_t ch = 0; ch < NCHANNELS; ch++){ - buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; + std::complex<float> mem[NUM_SAMPS_PER_BUFF * NCHANNELS]; + std::vector<std::complex<float>*> buffs(NCHANNELS); + for (size_t ch = 0; ch < NCHANNELS; ch++) { + buffs[ch] = &mem[ch * NUM_SAMPS_PER_BUFF]; } // simulate a failure on a channel (the last one) uhd::rx_metadata_t metadata; - xports[NCHANNELS-1]->set_simulate_io_error(true); + xports[NCHANNELS - 1]->set_simulate_io_error(true); std::cout << "exception check" << std::endl; - BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "sc16_item32_be"; - id.num_inputs = 1; + id.input_format = "sc16_item32_be"; + id.num_inputs = 1; id.output_format = "fc32"; - id.num_outputs = 1; + id.num_outputs = 1; vrt::if_packet_info_t ifpi; - ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; - ifpi.packet_count = 0; - ifpi.sob = true; - ifpi.eob = false; - ifpi.has_sid = false; - ifpi.has_cid = false; - ifpi.has_tsi = true; - ifpi.has_tsf = true; - ifpi.tsi = 0; - ifpi.tsf = 0; - ifpi.has_tlr = false; - - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; - static const size_t NUM_PKTS_TO_TEST = 30; + ifpi.packet_count = 0; + ifpi.sob = true; + ifpi.eob = false; + ifpi.has_sid = false; + ifpi.has_cid = false; + ifpi.has_tsi = true; + ifpi.has_tsf = true; + ifpi.tsi = 0; + ifpi.tsf = 0; + ifpi.has_tlr = false; + + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; + static const size_t NUM_PKTS_TO_TEST = 30; static const size_t NUM_SAMPS_PER_BUFF = 10; - static const size_t NCHANNELS = 4; + static const size_t NCHANNELS = 4; std::vector<mock_zero_copy::sptr> xports; for (size_t i = 0; i < NCHANNELS; i++) { - xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + xports.push_back( + boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); } - //generate a bunch of packets - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.num_payload_words32 = 10 + i%10; - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // generate a bunch of packets + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { + ifpi.num_payload_words32 = 10 + i % 10; + for (size_t ch = 0; ch < NCHANNELS; ch++) { std::vector<uint32_t> data(ifpi.num_payload_words32, 0); xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; - ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); + ifpi.tsf += ifpi.num_payload_words32 * size_t(TICK_RATE / SAMP_RATE); } - //create the super receive packet handler + // create the super receive packet handler sph::recv_packet_handler handler(NCHANNELS); handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - for (size_t ch = 0; ch < NCHANNELS; ch++){ + for (size_t ch = 0; ch < NCHANNELS; ch++) { mock_zero_copy::sptr xport = xports[ch]; handler.set_xport_chan_get_buff( - ch, - [xport](double timeout) { - return xport->get_recv_buff(timeout); - } - ); + ch, [xport](double timeout) { return xport->get_recv_buff(timeout); }); } handler.set_converter(id); - //check the received packets + // check the received packets size_t num_accum_samps = 0; - std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS]; - std::vector<std::complex<float> *> buffs(NCHANNELS); - for (size_t ch = 0; ch < NCHANNELS; ch++){ - buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF]; + std::complex<float> mem[NUM_SAMPS_PER_BUFF * NCHANNELS]; + std::vector<std::complex<float>*> buffs(NCHANNELS); + for (size_t ch = 0; ch < NCHANNELS; ch++) { + buffs[ch] = &mem[ch * NUM_SAMPS_PER_BUFF]; } uhd::rx_metadata_t metadata; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; - size_t num_samps_ret = handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + size_t num_samps_ret = + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_TS_CLOSE( + metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); BOOST_CHECK_EQUAL(num_samps_ret, 10UL); num_accum_samps += num_samps_ret; - if (not metadata.more_fragments) continue; + if (not metadata.more_fragments) + continue; - num_samps_ret = handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + num_samps_ret = handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE); BOOST_CHECK(not metadata.more_fragments); BOOST_CHECK_EQUAL(metadata.fragment_offset, 10UL); BOOST_CHECK(metadata.has_time_spec); - BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); - BOOST_CHECK_EQUAL(num_samps_ret, i%10); + BOOST_CHECK_TS_CLOSE( + metadata.time_spec, uhd::time_spec_t::from_ticks(num_accum_samps, SAMP_RATE)); + BOOST_CHECK_EQUAL(num_samps_ret, i % 10); num_accum_samps += num_samps_ret; } - //subsequent receives should be a timeout - for (size_t i = 0; i < 3; i++){ + // subsequent receives should be a timeout + for (size_t i = 0; i < 3; i++) { std::cout << "timeout check " << i << std::endl; - handler.recv( - buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true - ); + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true); BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); } - //simulate the transport failing - for (size_t ch = 0; ch < NCHANNELS; ch++){ + // simulate the transport failing + for (size_t ch = 0; ch < NCHANNELS; ch++) { xports[ch]->set_simulate_io_error(true); } - BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); + BOOST_REQUIRE_THROW( + handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); } diff --git a/host/tests/sph_send_test.cpp b/host/tests/sph_send_test.cpp index 2db80c8de..6de4c9ffa 100644 --- a/host/tests/sph_send_test.cpp +++ b/host/tests/sph_send_test.cpp @@ -5,14 +5,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> -#include "../lib/transport/super_send_packet_handler.hpp" #include "../common/mock_zero_copy.hpp" -#include <boost/shared_array.hpp> +#include "../lib/transport/super_send_packet_handler.hpp" #include <boost/bind.hpp> +#include <boost/shared_array.hpp> +#include <boost/test/unit_test.hpp> #include <complex> -#include <vector> #include <list> +#include <vector> using namespace uhd::transport; @@ -20,120 +20,110 @@ using namespace uhd::transport; BOOST_CHECK_CLOSE((a).get_real_secs(), (b).get_real_secs(), 0.001) //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; - //create the super send packet handler + // create the super send packet handler sph::send_packet_handler handler(1); handler.set_vrt_packer(&vrt::if_hdr_pack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); handler.set_xport_chan_get_buff( - 0, - [&xport](double timeout) { - return xport.get_send_buff(timeout); - } - ); + 0, [&xport](double timeout) { return xport.get_send_buff(timeout); }); handler.set_converter(id); handler.set_max_samples_per_packet(20); - //allocate metadata and buffer - std::vector<std::complex<float> > buff(20); + // allocate metadata and buffer + std::vector<std::complex<float>> buff(20); uhd::tx_metadata_t metadata; metadata.has_time_spec = true; - metadata.time_spec = uhd::time_spec_t(0.0); + metadata.time_spec = uhd::time_spec_t(0.0); - //generate the test data - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + // generate the test data + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { metadata.start_of_burst = (i == 0); - metadata.end_of_burst = (i == NUM_PKTS_TO_TEST-1); - const size_t num_sent = handler.send( - &buff.front(), 10 + i%10, metadata, 1.0 - ); - BOOST_CHECK_EQUAL(num_sent, 10 + i%10); + metadata.end_of_burst = (i == NUM_PKTS_TO_TEST - 1); + const size_t num_sent = handler.send(&buff.front(), 10 + i % 10, metadata, 1.0); + BOOST_CHECK_EQUAL(num_sent, 10 + i % 10); metadata.time_spec += uhd::time_spec_t(0, num_sent, SAMP_RATE); } - //check the sent packets + // check the sent packets size_t num_accum_samps = 0; vrt::if_packet_info_t ifpi; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; xport.pop_send_packet(ifpi); - BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10+i%10); + BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10 + i % 10); BOOST_CHECK(ifpi.has_tsf); - BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); + BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps * TICK_RATE / SAMP_RATE); BOOST_CHECK_EQUAL(ifpi.sob, i == 0); - BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1); + BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST - 1); num_accum_samps += ifpi.num_payload_words32; } } //////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){ -//////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode) +{ + //////////////////////////////////////////////////////////////////////// uhd::convert::id_type id; - id.input_format = "fc32"; - id.num_inputs = 1; + id.input_format = "fc32"; + id.num_inputs = 1; id.output_format = "sc16_item32_be"; - id.num_outputs = 1; + id.num_outputs = 1; mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); - static const double TICK_RATE = 100e6; - static const double SAMP_RATE = 10e6; + static const double TICK_RATE = 100e6; + static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; - //create the super send packet handler + // create the super send packet handler sph::send_packet_handler handler(1); handler.set_vrt_packer(&vrt::if_hdr_pack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); handler.set_xport_chan_get_buff( - 0, - [&xport](double timeout) { - return xport.get_send_buff(timeout); - } - ); + 0, [&xport](double timeout) { return xport.get_send_buff(timeout); }); handler.set_converter(id); handler.set_max_samples_per_packet(20); - //allocate metadata and buffer - std::vector<std::complex<float> > buff(20*NUM_PKTS_TO_TEST); + // allocate metadata and buffer + std::vector<std::complex<float>> buff(20 * NUM_PKTS_TO_TEST); uhd::tx_metadata_t metadata; metadata.start_of_burst = true; - metadata.end_of_burst = true; - metadata.has_time_spec = true; - metadata.time_spec = uhd::time_spec_t(0.0); + metadata.end_of_burst = true; + metadata.has_time_spec = true; + metadata.time_spec = uhd::time_spec_t(0.0); - //generate the test data - const size_t num_sent = handler.send( - &buff.front(), buff.size(), metadata, 1.0 - ); + // generate the test data + const size_t num_sent = handler.send(&buff.front(), buff.size(), metadata, 1.0); BOOST_CHECK_EQUAL(num_sent, buff.size()); - //check the sent packets + // check the sent packets size_t num_accum_samps = 0; vrt::if_packet_info_t ifpi; - for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ + for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) { std::cout << "data check " << i << std::endl; xport.pop_send_packet(ifpi); BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20UL); BOOST_CHECK(ifpi.has_tsf); - BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); + BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps * TICK_RATE / SAMP_RATE); BOOST_CHECK_EQUAL(ifpi.sob, i == 0); - BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1); + BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST - 1); num_accum_samps += ifpi.num_payload_words32; } } diff --git a/host/tests/stream_sig_test.cpp b/host/tests/stream_sig_test.cpp index 88344faf5..41c07c14f 100644 --- a/host/tests/stream_sig_test.cpp +++ b/host/tests/stream_sig_test.cpp @@ -5,14 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <iostream> -#include <boost/test/unit_test.hpp> #include <uhd/exception.hpp> #include <uhd/rfnoc/stream_sig.hpp> +#include <boost/test/unit_test.hpp> +#include <iostream> using namespace uhd::rfnoc; -BOOST_AUTO_TEST_CASE(test_stream_sig) { +BOOST_AUTO_TEST_CASE(test_stream_sig) +{ stream_sig_t stream_sig; BOOST_CHECK_EQUAL(stream_sig.item_type, ""); @@ -26,7 +27,8 @@ BOOST_AUTO_TEST_CASE(test_stream_sig) { std::cout << ss.str() << std::endl; } -BOOST_AUTO_TEST_CASE(test_stream_sig_compat) { +BOOST_AUTO_TEST_CASE(test_stream_sig_compat) +{ stream_sig_t upstream_sig; stream_sig_t downstream_sig; @@ -47,12 +49,13 @@ BOOST_AUTO_TEST_CASE(test_stream_sig_compat) { BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig)); downstream_sig.item_type = ""; BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig)); - upstream_sig.item_type = "sc16"; + upstream_sig.item_type = "sc16"; downstream_sig.item_type = "s8"; BOOST_CHECK(not stream_sig_t::is_compatible(upstream_sig, downstream_sig)); } -BOOST_AUTO_TEST_CASE(test_stream_sig_types) { +BOOST_AUTO_TEST_CASE(test_stream_sig_types) +{ stream_sig_t stream_sig; BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 0); stream_sig.item_type = "sc16"; diff --git a/host/tests/subdev_spec_test.cpp b/host/tests/subdev_spec_test.cpp index b87981392..533e8f90d 100644 --- a/host/tests/subdev_spec_test.cpp +++ b/host/tests/subdev_spec_test.cpp @@ -5,34 +5,35 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/usrp/subdev_spec.hpp> +#include <boost/test/unit_test.hpp> #include <iostream> -BOOST_AUTO_TEST_CASE(test_subdevice_spec){ +BOOST_AUTO_TEST_CASE(test_subdevice_spec) +{ std::cout << "Testing subdevice specification..." << std::endl; - //load the subdev spec with something + // load the subdev spec with something uhd::usrp::subdev_spec_t sd_spec; sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("A", "AB")); sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("B", "AB")); - //create a subdev_spec with something different + // create a subdev_spec with something different uhd::usrp::subdev_spec_t diff_sd_spec; diff_sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("B", "BA")); diff_sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("B", "BA")); - //convert to and from args string + // convert to and from args string std::cout << "Pretty Print: " << std::endl << sd_spec.to_pp_string(); std::string markup_str = sd_spec.to_string(); std::cout << "Markup String: " << markup_str << std::endl; uhd::usrp::subdev_spec_t new_sd_spec(markup_str); - //they should be the same size + // they should be the same size BOOST_REQUIRE_EQUAL(sd_spec.size(), new_sd_spec.size()); - //the contents should match - for (size_t i = 0; i < sd_spec.size(); i++){ + // the contents should match + for (size_t i = 0; i < sd_spec.size(); i++) { BOOST_CHECK_EQUAL(sd_spec.at(i).db_name, new_sd_spec.at(i).db_name); BOOST_CHECK_EQUAL(sd_spec.at(i).sd_name, new_sd_spec.at(i).sd_name); diff --git a/host/tests/system_time_test.cpp b/host/tests/system_time_test.cpp index 3fc759391..3f4f8a814 100644 --- a/host/tests/system_time_test.cpp +++ b/host/tests/system_time_test.cpp @@ -4,20 +4,21 @@ // SPDX-License-Identifier: GPL-3.0+ // -#include <boost/test/unit_test.hpp> -#include <uhd/types/time_spec.hpp> #include "system_time.hpp" -#include <iostream> -#include <iomanip> -#include <cstdint> +#include <uhd/types/time_spec.hpp> +#include <boost/test/unit_test.hpp> #include <chrono> +#include <cstdint> +#include <iomanip> +#include <iostream> #include <thread> -BOOST_AUTO_TEST_CASE(test_time_spec_get_system_time){ +BOOST_AUTO_TEST_CASE(test_time_spec_get_system_time) +{ std::cout << "Testing time specification get system time..." << std::endl; - //Not really checking for high resolution timing here, - //just need to check that system time is minimally working. + // Not really checking for high resolution timing here, + // just need to check that system time is minimally working. auto start = uhd::get_system_time(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); @@ -27,7 +28,6 @@ BOOST_AUTO_TEST_CASE(test_time_spec_get_system_time){ std::cout << "start: " << start.get_real_secs() << std::endl; std::cout << "stop: " << stop.get_real_secs() << std::endl; std::cout << "diff: " << diff.get_real_secs() << std::endl; - BOOST_CHECK(diff.get_real_secs() > 0); //assert positive - BOOST_CHECK(diff.get_real_secs() < 1.0); //assert under 1s + BOOST_CHECK(diff.get_real_secs() > 0); // assert positive + BOOST_CHECK(diff.get_real_secs() < 1.0); // assert under 1s } - diff --git a/host/tests/tasks_test.cpp b/host/tests/tasks_test.cpp index f3bb07653..c236287e3 100644 --- a/host/tests/tasks_test.cpp +++ b/host/tests/tasks_test.cpp @@ -5,24 +5,24 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/utils/tasks.hpp> -#include <thread> +#include <boost/test/unit_test.hpp> #include <chrono> -#include <vector> #include <iostream> +#include <thread> +#include <vector> void test_tasks_sleep(size_t usecs) { std::this_thread::sleep_for(std::chrono::milliseconds(usecs)); } -BOOST_AUTO_TEST_CASE(tasks_test) { - +BOOST_AUTO_TEST_CASE(tasks_test) +{ static const size_t N_TASKS = 100; std::vector<uhd::task::sptr> test_vec; for (size_t i = 0; i < N_TASKS; i++) { - test_vec.push_back(uhd::task::make([i](){ test_tasks_sleep(i); })); + test_vec.push_back(uhd::task::make([i]() { test_tasks_sleep(i); })); } } diff --git a/host/tests/tick_node_test.cpp b/host/tests/tick_node_test.cpp index 173481fb1..ccec67c43 100644 --- a/host/tests/tick_node_test.cpp +++ b/host/tests/tick_node_test.cpp @@ -18,7 +18,7 @@ class tick_aware_node : public test_node, public tick_node_ctrl public: typedef boost::shared_ptr<tick_aware_node> sptr; - tick_aware_node(const std::string &test_id) : test_node(test_id) {}; + tick_aware_node(const std::string& test_id) : test_node(test_id){}; }; /* class tick_aware_node */ @@ -28,10 +28,14 @@ class tick_setting_node : public test_node, public tick_node_ctrl public: typedef boost::shared_ptr<tick_setting_node> sptr; - tick_setting_node(const std::string &test_id, double tick_rate) : test_node(test_id), _tick_rate(tick_rate) {}; + tick_setting_node(const std::string& test_id, double tick_rate) + : test_node(test_id), _tick_rate(tick_rate){}; protected: - double _get_tick_rate() { return _tick_rate; }; + double _get_tick_rate() + { + return _tick_rate; + }; private: const double _tick_rate; @@ -39,7 +43,8 @@ private: }; /* class tick_setting_node */ #define MAKE_TICK_NODE(name) tick_aware_node::sptr name(new tick_aware_node(#name)); -#define MAKE_TICK_SETTING_NODE(name, rate) tick_setting_node::sptr name(new tick_setting_node(#name, rate)); +#define MAKE_TICK_SETTING_NODE(name, rate) \ + tick_setting_node::sptr name(new tick_setting_node(#name, rate)); BOOST_AUTO_TEST_CASE(test_simplest_downstream_search) { diff --git a/host/tests/time_spec_test.cpp b/host/tests/time_spec_test.cpp index 89a5370bd..dee8d414e 100644 --- a/host/tests/time_spec_test.cpp +++ b/host/tests/time_spec_test.cpp @@ -5,14 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/types/time_spec.hpp> +#include <stdint.h> +#include <boost/test/unit_test.hpp> #include <boost/thread.hpp> //sleep -#include <iostream> #include <iomanip> -#include <stdint.h> +#include <iostream> -BOOST_AUTO_TEST_CASE(test_time_spec_compare){ +BOOST_AUTO_TEST_CASE(test_time_spec_compare) +{ std::cout << "Testing time specification compare..." << std::endl; BOOST_CHECK(uhd::time_spec_t(2.0) == uhd::time_spec_t(2.0)); @@ -31,7 +32,8 @@ BOOST_AUTO_TEST_CASE(test_time_spec_compare){ #define CHECK_TS_EQUAL(lhs, rhs) \ BOOST_CHECK_CLOSE((lhs).get_real_secs(), (rhs).get_real_secs(), 0.001) -BOOST_AUTO_TEST_CASE(test_time_spec_arithmetic){ +BOOST_AUTO_TEST_CASE(test_time_spec_arithmetic) +{ std::cout << "Testing time specification arithmetic..." << std::endl; CHECK_TS_EQUAL(uhd::time_spec_t(2.3) + uhd::time_spec_t(1.0), uhd::time_spec_t(3.3)); @@ -40,7 +42,8 @@ BOOST_AUTO_TEST_CASE(test_time_spec_arithmetic){ CHECK_TS_EQUAL(uhd::time_spec_t(1.0) - uhd::time_spec_t(2.3), uhd::time_spec_t(-1.3)); } -BOOST_AUTO_TEST_CASE(test_time_spec_parts){ +BOOST_AUTO_TEST_CASE(test_time_spec_parts) +{ std::cout << "Testing time specification parts..." << std::endl; BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_full_secs(), 1); @@ -52,7 +55,8 @@ BOOST_AUTO_TEST_CASE(test_time_spec_parts){ BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).to_ticks(100), -110); } -BOOST_AUTO_TEST_CASE(test_time_spec_neg_values){ +BOOST_AUTO_TEST_CASE(test_time_spec_neg_values) +{ uhd::time_spec_t ts1(0.3); uhd::time_spec_t ts2(1, -0.9); std::cout << "ts1 " << ts1.get_real_secs() << std::endl; @@ -74,7 +78,7 @@ BOOST_AUTO_TEST_CASE(test_time_spec_neg_values){ BOOST_AUTO_TEST_CASE(test_time_large_ticks_to_time_spec) { std::cout << "sizeof(time_t) " << sizeof(time_t) << std::endl; - const uint64_t ticks0 = uint64_t(100e6*1360217663.739296); + const uint64_t ticks0 = uint64_t(100e6 * 1360217663.739296); const uhd::time_spec_t t0 = uhd::time_spec_t::from_ticks(ticks0, 100e6); std::cout << "t0.get_real_secs() " << t0.get_real_secs() << std::endl; std::cout << "t0.get_full_secs() " << t0.get_full_secs() << std::endl; @@ -84,11 +88,11 @@ BOOST_AUTO_TEST_CASE(test_time_large_ticks_to_time_spec) BOOST_AUTO_TEST_CASE(test_time_error_irrational_rate) { - static const double rate = 1625e3/6.0; - const long long tick_in = 23423436291667ll; + static const double rate = 1625e3 / 6.0; + const long long tick_in = 23423436291667ll; const uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(tick_in, rate); - const long long tick_out = ts.to_ticks(rate); - const long long err = tick_in - tick_out; + const long long tick_out = ts.to_ticks(rate); + const long long err = tick_in - tick_out; std::streamsize precision = std::cout.precision(); std::cout << std::setprecision(18); diff --git a/host/tests/vrt_test.cpp b/host/tests/vrt_test.cpp index 1b4df8fc7..ea639c65c 100644 --- a/host/tests/vrt_test.cpp +++ b/host/tests/vrt_test.cpp @@ -5,65 +5,63 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/test/unit_test.hpp> #include <uhd/transport/vrt_if_packet.hpp> #include <uhd/utils/byteswap.hpp> #include <boost/format.hpp> +#include <boost/test/unit_test.hpp> #include <cstdlib> #include <iostream> using namespace uhd::transport; -static void pack_and_unpack( - vrt::if_packet_info_t &if_packet_info_in -){ - if (if_packet_info_in.num_payload_bytes == 0) - { - if_packet_info_in.num_payload_bytes = if_packet_info_in.num_payload_words32 * sizeof(uint32_t); +static void pack_and_unpack(vrt::if_packet_info_t& if_packet_info_in) +{ + if (if_packet_info_in.num_payload_bytes == 0) { + if_packet_info_in.num_payload_bytes = + if_packet_info_in.num_payload_words32 * sizeof(uint32_t); } uint32_t packet_buff[2048]; - //pack metadata into a vrt header - vrt::if_hdr_pack_be( - packet_buff, if_packet_info_in - ); + // pack metadata into a vrt header + vrt::if_hdr_pack_be(packet_buff, if_packet_info_in); std::cout << std::endl; - for (size_t i = 0; i < 5; i++) - { - std::cout << boost::format("packet_buff[%u] = 0x%.8x") % i % uhd::byteswap(packet_buff[i]) << std::endl; + for (size_t i = 0; i < 5; i++) { + std::cout << boost::format("packet_buff[%u] = 0x%.8x") % i + % uhd::byteswap(packet_buff[i]) + << std::endl; } vrt::if_packet_info_t if_packet_info_out; - if_packet_info_out.link_type = if_packet_info_in.link_type; + if_packet_info_out.link_type = if_packet_info_in.link_type; if_packet_info_out.num_packet_words32 = if_packet_info_in.num_packet_words32; - //unpack the vrt header back into metadata - vrt::if_hdr_unpack_be( - packet_buff, if_packet_info_out - ); + // unpack the vrt header back into metadata + vrt::if_hdr_unpack_be(packet_buff, if_packet_info_out); - //check the the unpacked metadata is the same + // check the the unpacked metadata is the same BOOST_CHECK_EQUAL(if_packet_info_in.packet_count, if_packet_info_out.packet_count); - BOOST_CHECK_EQUAL(if_packet_info_in.num_header_words32, if_packet_info_out.num_header_words32); - BOOST_CHECK_EQUAL(if_packet_info_in.num_payload_words32, if_packet_info_out.num_payload_words32); + BOOST_CHECK_EQUAL( + if_packet_info_in.num_header_words32, if_packet_info_out.num_header_words32); + BOOST_CHECK_EQUAL( + if_packet_info_in.num_payload_words32, if_packet_info_out.num_payload_words32); BOOST_CHECK_EQUAL(if_packet_info_in.has_sid, if_packet_info_out.has_sid); - if (if_packet_info_in.has_sid and if_packet_info_out.has_sid){ + if (if_packet_info_in.has_sid and if_packet_info_out.has_sid) { BOOST_CHECK_EQUAL(if_packet_info_in.sid, if_packet_info_out.sid); } BOOST_CHECK_EQUAL(if_packet_info_in.has_cid, if_packet_info_out.has_cid); - if (if_packet_info_in.has_cid and if_packet_info_out.has_cid){ + if (if_packet_info_in.has_cid and if_packet_info_out.has_cid) { BOOST_CHECK_EQUAL(if_packet_info_in.cid, if_packet_info_out.cid); } BOOST_CHECK_EQUAL(if_packet_info_in.has_tsi, if_packet_info_out.has_tsi); - if (if_packet_info_in.has_tsi and if_packet_info_out.has_tsi){ + if (if_packet_info_in.has_tsi and if_packet_info_out.has_tsi) { BOOST_CHECK_EQUAL(if_packet_info_in.tsi, if_packet_info_out.tsi); } BOOST_CHECK_EQUAL(if_packet_info_in.has_tsf, if_packet_info_out.has_tsf); - if (if_packet_info_in.has_tsf and if_packet_info_out.has_tsf){ + if (if_packet_info_in.has_tsf and if_packet_info_out.has_tsf) { BOOST_CHECK_EQUAL(if_packet_info_in.tsf, if_packet_info_out.tsf); } BOOST_CHECK_EQUAL(if_packet_info_in.has_tlr, if_packet_info_out.has_tlr); - if (if_packet_info_in.has_tlr and if_packet_info_out.has_tlr){ + if (if_packet_info_in.has_tlr and if_packet_info_out.has_tlr) { BOOST_CHECK_EQUAL(if_packet_info_in.tlr, if_packet_info_out.tlr); } } @@ -73,102 +71,109 @@ static void pack_and_unpack( * The trailer is not tested as it is not convenient to do so. **********************************************************************/ -BOOST_AUTO_TEST_CASE(test_with_none){ +BOOST_AUTO_TEST_CASE(test_with_none) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.packet_count = 0; - if_packet_info.has_sid = false; - if_packet_info.has_cid = false; - if_packet_info.has_tsi = false; - if_packet_info.has_tsf = false; - if_packet_info.has_tlr = false; + if_packet_info.packet_count = 0; + if_packet_info.has_sid = false; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; if_packet_info.num_payload_words32 = 0; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_sid){ +BOOST_AUTO_TEST_CASE(test_with_sid) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.packet_count = 1; - if_packet_info.has_sid = true; - if_packet_info.has_cid = false; - if_packet_info.has_tsi = false; - if_packet_info.has_tsf = false; - if_packet_info.has_tlr = false; - if_packet_info.sid = std::rand(); + if_packet_info.packet_count = 1; + if_packet_info.has_sid = true; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; + if_packet_info.sid = std::rand(); if_packet_info.num_payload_words32 = 11; pack_and_unpack(if_packet_info); } static const bool cid_enb = false; -BOOST_AUTO_TEST_CASE(test_with_cid){ +BOOST_AUTO_TEST_CASE(test_with_cid) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.packet_count = 2; - if_packet_info.has_sid = false; - if_packet_info.has_cid = cid_enb; - if_packet_info.has_tsi = false; - if_packet_info.has_tsf = false; - if_packet_info.has_tlr = false; - if_packet_info.cid = std::rand(); + if_packet_info.packet_count = 2; + if_packet_info.has_sid = false; + if_packet_info.has_cid = cid_enb; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; + if_packet_info.cid = std::rand(); if_packet_info.num_payload_words32 = 22; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_time){ +BOOST_AUTO_TEST_CASE(test_with_time) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.packet_count = 3; - if_packet_info.has_sid = false; - if_packet_info.has_cid = false; - if_packet_info.has_tsi = true; - if_packet_info.has_tsf = true; - if_packet_info.has_tlr = false; - if_packet_info.tsi = std::rand(); - if_packet_info.tsf = std::rand(); + if_packet_info.packet_count = 3; + if_packet_info.has_sid = false; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = true; + if_packet_info.has_tsf = true; + if_packet_info.has_tlr = false; + if_packet_info.tsi = std::rand(); + if_packet_info.tsf = std::rand(); if_packet_info.num_payload_words32 = 33; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_all){ +BOOST_AUTO_TEST_CASE(test_with_all) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.packet_count = 4; - if_packet_info.has_sid = true; - if_packet_info.has_cid = cid_enb; - if_packet_info.has_tsi = true; - if_packet_info.has_tsf = true; - if_packet_info.has_tlr = false; - if_packet_info.sid = std::rand(); - if_packet_info.cid = std::rand(); - if_packet_info.tsi = std::rand(); - if_packet_info.tsf = std::rand(); + if_packet_info.packet_count = 4; + if_packet_info.has_sid = true; + if_packet_info.has_cid = cid_enb; + if_packet_info.has_tsi = true; + if_packet_info.has_tsf = true; + if_packet_info.has_tlr = false; + if_packet_info.sid = std::rand(); + if_packet_info.cid = std::rand(); + if_packet_info.tsi = std::rand(); + if_packet_info.tsf = std::rand(); if_packet_info.num_payload_words32 = 44; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_vrlp){ +BOOST_AUTO_TEST_CASE(test_with_vrlp) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_VRLP; - if_packet_info.packet_count = 3; - if_packet_info.has_sid = true; - if_packet_info.has_cid = false; - if_packet_info.has_tsi = false; - if_packet_info.has_tsf = true; - if_packet_info.has_tlr = true; - if_packet_info.tsi = std::rand(); - if_packet_info.tsf = std::rand(); + if_packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_VRLP; + if_packet_info.packet_count = 3; + if_packet_info.has_sid = true; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = true; + if_packet_info.has_tlr = true; + if_packet_info.tsi = std::rand(); + if_packet_info.tsf = std::rand(); if_packet_info.num_payload_words32 = 42; pack_and_unpack(if_packet_info); } -BOOST_AUTO_TEST_CASE(test_with_chdr){ +BOOST_AUTO_TEST_CASE(test_with_chdr) +{ vrt::if_packet_info_t if_packet_info; - if_packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; - if_packet_info.packet_count = 7; - if_packet_info.has_sid = true; - if_packet_info.has_cid = false; - if_packet_info.has_tsi = false; - if_packet_info.has_tsf = true; - if_packet_info.has_tlr = false; //tlr not suported in CHDR - if_packet_info.tsi = std::rand(); - if_packet_info.tsf = std::rand(); + if_packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; + if_packet_info.packet_count = 7; + if_packet_info.has_sid = true; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = true; + if_packet_info.has_tlr = false; // tlr not suported in CHDR + if_packet_info.tsi = std::rand(); + if_packet_info.tsf = std::rand(); if_packet_info.num_payload_words32 = 24; pack_and_unpack(if_packet_info); } diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp index 75bb1a5bb..e723b904a 100644 --- a/host/utils/b2xx_fx3_utils.cpp +++ b/host/utils/b2xx_fx3_utils.cpp @@ -5,50 +5,47 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/config.hpp> +#include <uhd/exception.hpp> +#include <uhd/transport/usb_control.hpp> +#include <uhd/transport/usb_device_handle.hpp> +#include <uhd/utils/paths.hpp> +#include <b200_iface.hpp> +#include <libusb.h> +#include <stdint.h> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/functional/hash.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/program_options.hpp> +#include <chrono> +#include <cmath> #include <cstdlib> #include <cstring> -#include <iostream> -#include <iomanip> #include <fstream> -#include <libusb.h> +#include <iomanip> +#include <iostream> #include <sstream> #include <string> -#include <cmath> -#include <cstring> -#include <chrono> #include <thread> -#include <stdint.h> -#include <boost/filesystem.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/format.hpp> -#include <boost/program_options.hpp> -#include <boost/functional/hash.hpp> - -#include <b200_iface.hpp> -#include <uhd/config.hpp> -#include <uhd/transport/usb_control.hpp> -#include <uhd/transport/usb_device_handle.hpp> -#include <uhd/exception.hpp> -#include <uhd/utils/paths.hpp> - namespace po = boost::program_options; namespace fs = boost::filesystem; -struct vid_pid_t { +struct vid_pid_t +{ uint16_t vid; uint16_t pid; }; -const static vid_pid_t known_vid_pids[] = { - {FX3_VID, FX3_DEFAULT_PID}, +const static vid_pid_t known_vid_pids[] = {{FX3_VID, FX3_DEFAULT_PID}, {FX3_VID, FX3_REENUM_PID}, {B200_VENDOR_ID, B200_PRODUCT_ID}, {B200_VENDOR_ID, B200MINI_PRODUCT_ID}, {B200_VENDOR_ID, B205MINI_PRODUCT_ID}, {B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID}, - {B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID} -}; -const static std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids, known_vid_pids + (sizeof(known_vid_pids) / sizeof(known_vid_pids[0]))); + {B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID}}; +const static std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids, + known_vid_pids + (sizeof(known_vid_pids) / sizeof(known_vid_pids[0]))); static const size_t EEPROM_INIT_VALUE_VECTOR_SIZE = 8; static uhd::byte_vector_t construct_eeprom_init_value_vector(uint16_t vid, uint16_t pid) @@ -65,19 +62,25 @@ static uhd::byte_vector_t construct_eeprom_init_value_vector(uint16_t vid, uint1 return init_values; } -//!used with lexical cast to parse a hex string -template <class T> struct to_hex{ +//! used with lexical cast to parse a hex string +template <class T> struct to_hex +{ T value; - operator T() const {return value;} - friend std::istream& operator>>(std::istream& in, to_hex& out){ + operator T() const + { + return value; + } + friend std::istream& operator>>(std::istream& in, to_hex& out) + { in >> std::hex >> out.value; return in; } }; -//!parse hex-formatted ASCII text into an int -uint16_t atoh(const std::string &string){ - if (string.substr(0, 2) == "0x"){ +//! parse hex-formatted ASCII text into an int +uint16_t atoh(const std::string& string) +{ + if (string.substr(0, 2) == "0x") { std::stringstream interpreter(string); to_hex<uint16_t> hh; interpreter >> hh; @@ -98,42 +101,39 @@ int reset_usb() /* Check each of the possible paths above to find which ones this system * uses. */ - for(std::set<fs::path>::iterator found = path_list.begin(); - found != path_list.end(); ++found) { - - if(fs::exists(*found)) { - + for (std::set<fs::path>::iterator found = path_list.begin(); found != path_list.end(); + ++found) { + if (fs::exists(*found)) { fs::path devpath = *found; std::set<fs::path> globbed; /* Now, glob all of the files in the directory. */ fs::directory_iterator end_itr; - for(fs::directory_iterator itr(devpath); itr != end_itr; ++itr) { + for (fs::directory_iterator itr(devpath); itr != end_itr; ++itr) { globbed.insert((*itr).path()); } /* Check each file path string to see if it is a device file. */ - for(std::set<fs::path>::iterator it = globbed.begin(); - it != globbed.end(); ++it) { - + for (std::set<fs::path>::iterator it = globbed.begin(); it != globbed.end(); + ++it) { std::string file = fs::path((*it).filename()).string(); if (file.length() < 5) continue; - if(file.compare(0, 5, "0000:") == 0) { + if (file.compare(0, 5, "0000:") == 0) { /* Un-bind the device. */ - std::fstream unbind((devpath.string() + "unbind").c_str(), - std::fstream::out); + std::fstream unbind( + (devpath.string() + "unbind").c_str(), std::fstream::out); unbind << file; unbind.close(); /* Re-bind the device. */ - std::cout << "Re-binding: " << file << " in " - << devpath.string() << std::endl; - std::fstream bind((devpath.string() + "bind").c_str(), - std::fstream::out); + std::cout << "Re-binding: " << file << " in " << devpath.string() + << std::endl; + std::fstream bind( + (devpath.string() + "bind").c_str(), std::fstream::out); bind << file; bind.close(); } @@ -144,7 +144,8 @@ int reset_usb() return 0; } -uhd::transport::usb_device_handle::sptr open_device(const uint16_t vid, const uint16_t pid, const bool user_supplied = false) +uhd::transport::usb_device_handle::sptr open_device( + const uint16_t vid, const uint16_t pid, const bool user_supplied = false) { std::vector<uhd::transport::usb_device_handle::sptr> handles; uhd::transport::usb_device_handle::sptr handle; @@ -152,60 +153,70 @@ uhd::transport::usb_device_handle::sptr open_device(const uint16_t vid, const ui try { // try caller's VID/PID first - std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> vid_pid_pair_list(1,uhd::transport::usb_device_handle::vid_pid_pair_t(vid,pid)); + std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> vid_pid_pair_list( + 1, uhd::transport::usb_device_handle::vid_pid_pair_t(vid, pid)); handles = uhd::transport::usb_device_handle::get_device_list(vid_pid_pair_list); - if (handles.size() == 0) - { - if (user_supplied) - { - std::cerr << (boost::format("Failed to open device with VID 0x%04x and PID 0x%04x - trying other known VID/PIDs") % vid % pid).str() << std::endl; + if (handles.size() == 0) { + if (user_supplied) { + std::cerr << (boost::format("Failed to open device with VID 0x%04x and " + "PID 0x%04x - trying other known VID/PIDs") + % vid % pid) + .str() + << std::endl; } // try known VID/PIDs next - for (size_t i = 0; handles.size() == 0 && i < known_vid_pid_vector.size(); i++) - { + for (size_t i = 0; handles.size() == 0 && i < known_vid_pid_vector.size(); + i++) { vp = known_vid_pid_vector[i]; - handles = uhd::transport::usb_device_handle::get_device_list(vp.vid, vp.pid); + handles = + uhd::transport::usb_device_handle::get_device_list(vp.vid, vp.pid); } - } - if (handles.size() > 0) - { + if (handles.size() > 0) { handle = handles[0]; - std::cout << (boost::format("Device opened (VID=0x%04x,PID=0x%04x)") % vp.vid % vp.pid).str() << std::endl; + std::cout << (boost::format("Device opened (VID=0x%04x,PID=0x%04x)") % vp.vid + % vp.pid) + .str() + << std::endl; } if (!handle) std::cerr << "Cannot open device" << std::endl; - } - catch(const std::exception &) { + } catch (const std::exception&) { std::cerr << "Failed to communicate with the device!" << std::endl; - #ifdef UHD_PLATFORM_WIN32 - std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/manual/page_transport.html" << std::endl; - #endif /* UHD_PLATFORM_WIN32 */ +#ifdef UHD_PLATFORM_WIN32 + std::cerr << "The necessary drivers are not installed. Read the UHD Transport " + "Application Notes for " + "details:\nhttp://files.ettus.com/manual/page_transport.html" + << std::endl; +#endif /* UHD_PLATFORM_WIN32 */ handle.reset(); } return handle; } -b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr &handle) +b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr& handle) { b200_iface::sptr b200; try { - uhd::transport::usb_control::sptr usb_ctrl = uhd::transport::usb_control::make(handle, 0); + uhd::transport::usb_control::sptr usb_ctrl = + uhd::transport::usb_control::make(handle, 0); b200 = b200_iface::make(usb_ctrl); if (!b200) std::cerr << "Cannot create device interface" << std::endl; - } - catch(const std::exception &) { + } catch (const std::exception&) { std::cerr << "Failed to communicate with the device!" << std::endl; - #ifdef UHD_PLATFORM_WIN32 - std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/manual/page_transport.html" << std::endl; - #endif /* UHD_PLATFORM_WIN32 */ +#ifdef UHD_PLATFORM_WIN32 + std::cerr << "The necessary drivers are not installed. Read the UHD Transport " + "Application Notes for " + "details:\nhttp://files.ettus.com/manual/page_transport.html" + << std::endl; +#endif /* UHD_PLATFORM_WIN32 */ b200.reset(); } @@ -216,7 +227,7 @@ int read_eeprom(b200_iface::sptr& b200, uhd::byte_vector_t& data) { try { data = b200->read_eeprom(0x0, 0x0, 8); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while reading EEPROM: " << e.what() << std::endl; return -1; } @@ -227,8 +238,8 @@ int read_eeprom(b200_iface::sptr& b200, uhd::byte_vector_t& data) int write_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) { try { - b200->write_eeprom(0x0, 0x0, data); - } catch (std::exception &e) { + b200->write_eeprom(0x0, 0x0, data); + } catch (std::exception& e) { std::cerr << "Exception while writing EEPROM: " << e.what() << std::endl; return -1; } @@ -243,16 +254,17 @@ int verify_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) if (read_eeprom(b200, read_bytes)) return -1; - if (data.size() != read_bytes.size()) - { - std::cerr << "ERROR: Only able to verify first " << std::min(data.size(), read_bytes.size()) << " bytes." << std::endl; + if (data.size() != read_bytes.size()) { + std::cerr << "ERROR: Only able to verify first " + << std::min(data.size(), read_bytes.size()) << " bytes." << std::endl; verified = false; } for (size_t i = 0; i < std::min(data.size(), read_bytes.size()); i++) { if (data[i] != read_bytes[i]) { verified = false; - std::cerr << "Byte " << i << " Expected: " << data[i] << ", Got: " << read_bytes[i] << std::endl; + std::cerr << "Byte " << i << " Expected: " << data[i] + << ", Got: " << read_bytes[i] << std::endl; } } @@ -285,39 +297,32 @@ int erase_eeprom(b200_iface::sptr& b200) return 0; } -int32_t main(int32_t argc, char *argv[]) { +int32_t main(int32_t argc, char* argv[]) +{ uint16_t vid, pid; std::string pid_str, vid_str, fw_file, fpga_file, writevid_str, writepid_str; bool user_supplied_vid_pid = false; po::options_description visible("Allowed options"); - visible.add_options() - ("help,h", "help message") - ("vid,v", po::value<std::string>(&vid_str), - "Specify VID of device to use.") - ("pid,p", po::value<std::string>(&pid_str), - "Specify PID of device to use.") - ("speed,S", "Read back the USB mode currently in use.") - ("reset-device,D", "Reset the B2xx Device.") - ("reset-fpga,F", "Reset the FPGA (does not require re-programming.") - ("reset-usb,U", "Reset the USB subsystem on your host computer.") - ("load-fw,W", po::value<std::string>(&fw_file), - "Load a firmware (hex) file into the FX3.") - ("load-fpga,L", po::value<std::string>(&fpga_file), - "Load a FPGA (bin) file into the FPGA.") - ; + visible.add_options()("help,h", "help message")( + "vid,v", po::value<std::string>(&vid_str), "Specify VID of device to use.")( + "pid,p", po::value<std::string>(&pid_str), "Specify PID of device to use.")( + "speed,S", "Read back the USB mode currently in use.")( + "reset-device,D", "Reset the B2xx Device.")( + "reset-fpga,F", "Reset the FPGA (does not require re-programming.")( + "reset-usb,U", "Reset the USB subsystem on your host computer.")("load-fw,W", + po::value<std::string>(&fw_file), + "Load a firmware (hex) file into the FX3.")("load-fpga,L", + po::value<std::string>(&fpga_file), + "Load a FPGA (bin) file into the FPGA."); // Hidden options provided for testing - use at your own risk! po::options_description hidden("Hidden options"); - hidden.add_options() - ("init-device,I", "Initialize a B2xx device.") - ("uninit-device", "Uninitialize a B2xx device.") - ("read-eeprom,R", "Read first 8 bytes of EEPROM") - ("erase-eeprom,E", "Erase first 8 bytes of EEPROM") - ("write-vid", po::value<std::string>(&writevid_str), - "Write VID field of EEPROM") - ("write-pid", po::value<std::string>(&writepid_str), - "Write PID field of EEPROM"); + hidden.add_options()("init-device,I", "Initialize a B2xx device.")("uninit-device", + "Uninitialize a B2xx device.")("read-eeprom,R", "Read first 8 bytes of EEPROM")( + "erase-eeprom,E", "Erase first 8 bytes of EEPROM")( + "write-vid", po::value<std::string>(&writevid_str), "Write VID field of EEPROM")( + "write-pid", po::value<std::string>(&writepid_str), "Write PID field of EEPROM"); po::options_description desc; desc.add(visible); @@ -328,16 +333,17 @@ int32_t main(int32_t argc, char *argv[]) { try { po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while parsing arguments: " << e.what() << std::endl; std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; return ~0; } - if (vm.count("help")){ + if (vm.count("help")) { try { std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; - } catch(...) {} + } catch (...) { + } return ~0; } @@ -348,15 +354,14 @@ int32_t main(int32_t argc, char *argv[]) { uhd::transport::usb_device_handle::sptr handle; b200_iface::sptr b200; - vid = B200_VENDOR_ID; // Default - pid = B200_PRODUCT_ID; // Default - if (vm.count("vid") && vm.count("pid")) - { + vid = B200_VENDOR_ID; // Default + pid = B200_PRODUCT_ID; // Default + if (vm.count("vid") && vm.count("pid")) { try { vid = atoh(vid_str); pid = atoh(pid_str); - } catch (std::exception &e) { - std::cerr << "Exception while parsing VID and PID: " << e.what() << std:: endl; + } catch (std::exception& e) { + std::cerr << "Exception while parsing VID and PID: " << e.what() << std::endl; return ~0; } user_supplied_vid_pid = true; @@ -374,14 +379,13 @@ int32_t main(int32_t argc, char *argv[]) { return -1; std::cout << " Control of B2xx granted..." << std::endl << std::endl; - // if we are supposed to load a new firmware image and one already exists, reset the FX3 so we can load the new one - if (vm.count("load-fw") && handle->firmware_loaded()) - { + // if we are supposed to load a new firmware image and one already exists, reset the + // FX3 so we can load the new one + if (vm.count("load-fw") && handle->firmware_loaded()) { std::cout << "Overwriting existing firmware" << std::endl; // before we reset, make sure we have a good firmware file - if(!(fs::exists(fw_file))) - { + if (!(fs::exists(fw_file))) { std::cerr << "Invalid firmware filepath: " << fw_file << std::endl; return -1; } @@ -389,14 +393,15 @@ int32_t main(int32_t argc, char *argv[]) { // reset the device try { b200->reset_fx3(); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while reseting FX3: " << e.what() << std::endl; } // re-open device b200.reset(); handle.reset(); - std::this_thread::sleep_for(std::chrono::seconds(2)); // wait 2 seconds for FX3 to reset + std::this_thread::sleep_for( + std::chrono::seconds(2)); // wait 2 seconds for FX3 to reset handle = open_device(vid, pid); if (!handle) return -1; @@ -406,19 +411,18 @@ int32_t main(int32_t argc, char *argv[]) { } // Check to make sure firmware is loaded - if (!(handle->firmware_loaded())) - { + if (!(handle->firmware_loaded())) { std::cout << "Loading firmware" << std::endl; if (fw_file.empty()) fw_file = uhd::find_image_path(B200_FW_FILE_NAME); - if(fw_file.empty()) { + if (fw_file.empty()) { std::cerr << "Firmware image not found!" << std::endl; return -1; } - if(!(fs::exists(fw_file))) { + if (!(fs::exists(fw_file))) { std::cerr << "Invalid filepath: " << fw_file << std::endl; return -1; } @@ -426,7 +430,7 @@ int32_t main(int32_t argc, char *argv[]) { // load firmware try { b200->load_firmware(fw_file); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while loading firmware: " << e.what() << std::endl; return ~0; } @@ -445,8 +449,7 @@ int32_t main(int32_t argc, char *argv[]) { } // Added for testing purposes - not exposed - if (vm.count("read-eeprom")) - { + if (vm.count("read-eeprom")) { uhd::byte_vector_t data; if (read_eeprom(b200, data)) @@ -459,8 +462,7 @@ int32_t main(int32_t argc, char *argv[]) { } // Added for testing purposes - not exposed - if (vm.count("erase-eeprom")) - { + if (vm.count("erase-eeprom")) { if (erase_eeprom(b200)) return -1; @@ -470,90 +472,90 @@ int32_t main(int32_t argc, char *argv[]) { } // Added for testing purposes - not exposed - if (vm.count("uninit-device")) - { + if (vm.count("uninit-device")) { // erase EEPROM erase_eeprom(b200); - std::cout << "EEPROM uninitialized, resetting device..." - << std::endl << std::endl; + std::cout << "EEPROM uninitialized, resetting device..." << std::endl + << std::endl; // reset the device try { b200->reset_fx3(); - } catch (uhd::exception &e) { + } catch (uhd::exception& e) { std::cerr << "Exception while resetting FX3: " << e.what() << std::endl; return -1; } - std::cout << "Uninitialization Process Complete." - << std::endl << std::endl; + std::cout << "Uninitialization Process Complete." << std::endl << std::endl; return 0; } /* If we are initializing the device, the VID/PID should default to the * Cypress VID/PID for the initial FW load, but we can initialize from any state. */ - if (vm.count("init-device")) - { + if (vm.count("init-device")) { uint16_t writevid = B200_VENDOR_ID; uint16_t writepid = B200_PRODUCT_ID; /* Now, initialize the device. */ - // Added for testing purposes - not exposed - if (vm.count("write-vid") && vm.count("write-pid")) - { + // Added for testing purposes - not exposed + if (vm.count("write-vid") && vm.count("write-pid")) { try { - writevid = atoh(writevid_str); - writepid = atoh(writepid_str); - } catch (std::exception &e) { - std::cerr << "Exception while parsing write VID and PID: " << e.what() << std:: endl; - return ~0; + writevid = atoh(writevid_str); + writepid = atoh(writepid_str); + } catch (std::exception& e) { + std::cerr << "Exception while parsing write VID and PID: " << e.what() + << std::endl; + return ~0; } } std::cout << "Writing VID and PID to EEPROM..." << std::endl << std::endl; - if (write_and_verify_eeprom(b200, construct_eeprom_init_value_vector(writevid, writepid))) return -1; + if (write_and_verify_eeprom( + b200, construct_eeprom_init_value_vector(writevid, writepid))) + return -1; - std::cout << "EEPROM initialized, resetting device..." - << std::endl << std::endl; + std::cout << "EEPROM initialized, resetting device..." << std::endl << std::endl; /* Reset the device! */ try { b200->reset_fx3(); - } catch (const std::exception &e) { + } catch (const std::exception& e) { std::cerr << "Exception while resetting device: " << e.what() << std::endl; return -1; } - std::cout << "Initialization Process Complete." - << std::endl << std::endl; + std::cout << "Initialization Process Complete." << std::endl << std::endl; return 0; } uint8_t data_buffer[16]; memset(data_buffer, 0x0, sizeof(data_buffer)); - if (vm.count("speed")){ + if (vm.count("speed")) { uint8_t speed; - try {speed = b200->get_usb_speed();} - catch (uhd::exception &e) { + try { + speed = b200->get_usb_speed(); + } catch (uhd::exception& e) { std::cerr << "Exception while getting USB speed: " << e.what() << std::endl; return -1; } - std::cout << "Currently operating at USB " << (int) speed << std::endl; + std::cout << "Currently operating at USB " << (int)speed << std::endl; } if (vm.count("reset-device")) { - try {b200->reset_fx3();} - catch (uhd::exception &e) { + try { + b200->reset_fx3(); + } catch (uhd::exception& e) { std::cerr << "Exception while resetting FX3: " << e.what() << std::endl; return -1; } } else if (vm.count("reset-fpga")) { - try {b200->set_fpga_reset_pin(true);} - catch (uhd::exception &e) { + try { + b200->set_fpga_reset_pin(true); + } catch (uhd::exception& e) { std::cerr << "Exception while resetting FPGA: " << e.what() << std::endl; return -1; } @@ -561,24 +563,24 @@ int32_t main(int32_t argc, char *argv[]) { } else if (vm.count("load-fpga")) { std::cout << "Loading FPGA image (" << fpga_file << ")" << std::endl; uint32_t fx3_state; - try {fx3_state = b200->load_fpga(fpga_file);} // returns 0 on success, or FX3 state on error - catch (uhd::exception &e) { + try { + fx3_state = b200->load_fpga(fpga_file); + } // returns 0 on success, or FX3 state on error + catch (uhd::exception& e) { std::cerr << "Exception while loading FPGA: " << e.what() << std::endl; return ~0; } if (fx3_state != 0) { - std::cerr << std::flush << "Error loading FPGA. FX3 state (" - << fx3_state << "): " << b200_iface::fx3_state_string(fx3_state) << std::endl; + std::cerr << std::flush << "Error loading FPGA. FX3 state (" << fx3_state + << "): " << b200_iface::fx3_state_string(fx3_state) << std::endl; return ~0; } - std::cout << "FPGA load complete, releasing USB interface..." - << std::endl; + std::cout << "FPGA load complete, releasing USB interface..." << std::endl; } std::cout << "Operation complete! I did it! I did it!" << std::endl; return 0; } - diff --git a/host/utils/converter_benchmark.cpp b/host/utils/converter_benchmark.cpp index cb8cce519..07aec9170 100644 --- a/host/utils/converter_benchmark.cpp +++ b/host/utils/converter_benchmark.cpp @@ -5,32 +5,30 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> -#include <uhd/types/dict.hpp> #include <uhd/convert.hpp> #include <uhd/exception.hpp> -#include <boost/program_options.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/utils/safe_main.hpp> +#include <stdint.h> +#include <boost/algorithm/string.hpp> #include <boost/format.hpp> -#include <boost/timer.hpp> #include <boost/lexical_cast.hpp> -#include <boost/algorithm/string.hpp> -#include <iostream> +#include <boost/program_options.hpp> +#include <boost/timer.hpp> +#include <complex> #include <iomanip> +#include <iostream> #include <map> -#include <complex> -#include <stdint.h> namespace po = boost::program_options; using namespace uhd::convert; -enum buf_init_t { - RANDOM, INC -}; +enum buf_init_t { RANDOM, INC }; // Convert `sc16_item32_le' -> `sc16' // Finds the first _ in format and returns the string // until then. Returns the entire string if no _ is found. -std::string format_to_type(const std::string &format) +std::string format_to_type(const std::string& format) { std::string ret_val = ""; for (size_t i = 0; i < format.length(); i++) { @@ -44,10 +42,8 @@ std::string format_to_type(const std::string &format) } void configure_conv( - converter::sptr conv, - const std::string &in_type, - const std::string &out_type -) { + converter::sptr conv, const std::string& in_type, const std::string& out_type) +{ if (in_type == "sc16") { if (out_type == "fc32") { std::cout << "Setting scalar to 32767." << std::endl; @@ -68,21 +64,19 @@ void configure_conv( } template <typename T> -void init_random_vector_complex_float(std::vector<char> &buf_ptr, const size_t n_items) +void init_random_vector_complex_float(std::vector<char>& buf_ptr, const size_t n_items) { - std::complex<T> * const buf = reinterpret_cast<std::complex<T> * const>(&buf_ptr[0]); + std::complex<T>* const buf = reinterpret_cast<std::complex<T>* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = std::complex<T>( - T(std::rand()/(RAND_MAX/2.0) - 1), - T(std::rand()/(RAND_MAX/2.0) - 1) - ); + T(std::rand() / (RAND_MAX / 2.0) - 1), T(std::rand() / (RAND_MAX / 2.0) - 1)); } } template <typename T> -void init_random_vector_complex_int(std::vector<char> &buf_ptr, const size_t n_items) +void init_random_vector_complex_int(std::vector<char>& buf_ptr, const size_t n_items) { - std::complex<T> * const buf = reinterpret_cast<std::complex<T> * const>(&buf_ptr[0]); + std::complex<T>* const buf = reinterpret_cast<std::complex<T>* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = std::complex<T>(T(std::rand()), T(std::rand())); } @@ -96,45 +90,45 @@ struct item32_sc12_3x }; template <typename T> -void init_random_vector_complex_sc12(std::vector<char> &buf_ptr, const size_t n_items) +void init_random_vector_complex_sc12(std::vector<char>& buf_ptr, const size_t n_items) { - item32_sc12_3x *const buf = reinterpret_cast<item32_sc12_3x * const>(&buf_ptr[0]); - if (n_items % 4) throw std::invalid_argument(""); + item32_sc12_3x* const buf = reinterpret_cast<item32_sc12_3x* const>(&buf_ptr[0]); + if (n_items % 4) + throw std::invalid_argument(""); for (size_t i = 0; i < n_items / 4; i++) { int16_t iq[8]; - for (auto &k : iq) k = rand() & 0xfff; - buf[i].line0 = iq[0] << 20 | iq[1] << 8 | iq[2] >> 4; + for (auto& k : iq) + k = rand() & 0xfff; + buf[i].line0 = iq[0] << 20 | iq[1] << 8 | iq[2] >> 4; buf[i].line1 = iq[2] << 28 | iq[3] << 16 | iq[4] << 4 | iq[5] >> 8; buf[i].line2 = iq[5] << 24 | iq[6] << 12 | iq[7] << 0; } } template <typename T> -void init_random_vector_real_int(std::vector<char> &buf_ptr, size_t n_items) +void init_random_vector_real_int(std::vector<char>& buf_ptr, size_t n_items) { - T * const buf = reinterpret_cast<T * const>(&buf_ptr[0]); + T* const buf = reinterpret_cast<T* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = T(std::rand()); } } // Fill a buffer with increasing numbers -template <typename T> -void init_inc_vector(std::vector<char> &buf_ptr, size_t n_items) +template <typename T> void init_inc_vector(std::vector<char>& buf_ptr, size_t n_items) { - T * const buf = reinterpret_cast<T * const>(&buf_ptr[0]); + T* const buf = reinterpret_cast<T* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = T(i); } } -void init_buffers( - std::vector< std::vector<char> > &buf, - const std::string &type, - size_t bytes_per_item, - buf_init_t buf_seed_mode -) { +void init_buffers(std::vector<std::vector<char>>& buf, + const std::string& type, + size_t bytes_per_item, + buf_init_t buf_seed_mode) +{ if (buf.empty()) { return; } @@ -144,26 +138,25 @@ void init_buffers( if (buf_seed_mode == INC) { for (size_t i = 0; i < buf.size(); i++) { if (type == "sc8") { - init_inc_vector< std::complex<int8_t> >(buf[i], n_items); + init_inc_vector<std::complex<int8_t>>(buf[i], n_items); } else if (type == "sc16") { - init_inc_vector< std::complex<int16_t> >(buf[i], n_items); + init_inc_vector<std::complex<int16_t>>(buf[i], n_items); } else if (type == "sc32") { - init_inc_vector< std::complex<int32_t> >(buf[i], n_items); + init_inc_vector<std::complex<int32_t>>(buf[i], n_items); } else if (type == "fc32") { - init_inc_vector< std::complex<float> >(buf[i], n_items); + init_inc_vector<std::complex<float>>(buf[i], n_items); } else if (type == "fc64") { - init_inc_vector< std::complex<double> >(buf[i], n_items); + init_inc_vector<std::complex<double>>(buf[i], n_items); } else if (type == "s8") { - init_inc_vector< int8_t >(buf[i], n_items); + init_inc_vector<int8_t>(buf[i], n_items); } else if (type == "s16") { - init_inc_vector< int16_t >(buf[i], n_items); + init_inc_vector<int16_t>(buf[i], n_items); } else if (type == "item32") { - init_inc_vector< uint32_t >(buf[i], n_items); + init_inc_vector<uint32_t>(buf[i], n_items); init_random_vector_real_int<uint32_t>(buf[i], n_items); } else { - throw uhd::runtime_error(str( - boost::format("Cannot handle data type: %s") % type - )); + throw uhd::runtime_error( + str(boost::format("Cannot handle data type: %s") % type)); } } @@ -193,21 +186,19 @@ void init_buffers( } else if (type == "item32") { init_random_vector_real_int<uint32_t>(buf[i], n_items); } else { - throw uhd::runtime_error(str( - boost::format("Cannot handle data type: %s") % type - )); + throw uhd::runtime_error( + str(boost::format("Cannot handle data type: %s") % type)); } } } // Returns time elapsed -double run_benchmark( - converter::sptr conv, - const std::vector<const void *> &input_buf_refs, - const std::vector<void *> &output_buf_refs, - size_t n_items, - size_t iterations -) { +double run_benchmark(converter::sptr conv, + const std::vector<const void*>& input_buf_refs, + const std::vector<void*>& output_buf_refs, + size_t n_items, + size_t iterations) +{ boost::timer benchmark_timer; for (size_t i = 0; i < iterations; i++) { conv->conv(input_buf_refs, output_buf_refs, n_items); @@ -215,71 +206,58 @@ double run_benchmark( return benchmark_timer.elapsed(); } -template <typename T> -std::string void_ptr_to_hexstring(const void *v_ptr, size_t index) +template <typename T> std::string void_ptr_to_hexstring(const void* v_ptr, size_t index) { - const T *ptr = reinterpret_cast<const T *>(v_ptr); + const T* ptr = reinterpret_cast<const T*>(v_ptr); return str(boost::format("%X") % ptr[index]); } -std::string item_to_hexstring( - const void *v_ptr, - size_t index, - const std::string &type -) { +std::string item_to_hexstring(const void* v_ptr, size_t index, const std::string& type) +{ if (type == "fc32") { return void_ptr_to_hexstring<uint64_t>(v_ptr, index); - } - else if (type == "sc16" || type == "item32") { + } else if (type == "sc16" || type == "item32") { return void_ptr_to_hexstring<uint32_t>(v_ptr, index); - } - else if (type == "sc8" || type == "s16") { + } else if (type == "sc8" || type == "s16") { return void_ptr_to_hexstring<uint16_t>(v_ptr, index); - } - else if (type == "u8") { + } else if (type == "u8") { return void_ptr_to_hexstring<uint8_t>(v_ptr, index); - } - else { + } else { return str(boost::format("<unhandled data type: %s>") % type); } } std::string item_to_string( - const void *v_ptr, - size_t index, - const std::string &type, - const bool print_hex -) { + const void* v_ptr, size_t index, const std::string& type, const bool print_hex) +{ if (print_hex) { return item_to_hexstring(v_ptr, index, type); } if (type == "sc16") { - const std::complex<int16_t> *ptr = reinterpret_cast<const std::complex<int16_t> *>(v_ptr); + const std::complex<int16_t>* ptr = + reinterpret_cast<const std::complex<int16_t>*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "sc8") { - const std::complex<int8_t> *ptr = reinterpret_cast<const std::complex<int8_t> *>(v_ptr); + } else if (type == "sc8") { + const std::complex<int8_t>* ptr = + reinterpret_cast<const std::complex<int8_t>*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "fc32") { - const std::complex<float> *ptr = reinterpret_cast<const std::complex<float> *>(v_ptr); + } else if (type == "fc32") { + const std::complex<float>* ptr = + reinterpret_cast<const std::complex<float>*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "item32") { - const uint32_t *ptr = reinterpret_cast<const uint32_t *>(v_ptr); + } else if (type == "item32") { + const uint32_t* ptr = reinterpret_cast<const uint32_t*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "s16") { - const int16_t *ptr = reinterpret_cast<const int16_t *>(v_ptr); + } else if (type == "s16") { + const int16_t* ptr = reinterpret_cast<const int16_t*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else { + } else { return str(boost::format("<unhandled data type: %s>") % type); } } -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string in_format, out_format; std::string priorities; @@ -311,15 +289,19 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ - std::cout << boost::format("UHD Converter Benchmark Tool %s") % desc << std::endl << std::endl; - std::cout << " Use this to benchmark or debug converters." << std::endl - << " When using as a benchmark tool, it will output the execution time\n" - " for every conversion run in CSV format to stdout. Every line between\n" - " the output delimiters {{{ }}} is of the format: <PRIO>,<TIME IN MILLISECONDS>\n" - " When using for converter debugging, every line is formatted as\n" - " <INPUT_VALUE>,<OUTPUT_VALUE>\n" << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("UHD Converter Benchmark Tool %s") % desc << std::endl + << std::endl; + std::cout + << " Use this to benchmark or debug converters." << std::endl + << " When using as a benchmark tool, it will output the execution time\n" + " for every conversion run in CSV format to stdout. Every line between\n" + " the output delimiters {{{ }}} is of the format: <PRIO>,<TIME IN " + "MILLISECONDS>\n" + " When using for converter debugging, every line is formatted as\n" + " <INPUT_VALUE>,<OUTPUT_VALUE>\n" + << std::endl; return EXIT_FAILURE; } @@ -329,7 +311,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } else if (seed_mode == "random") { buf_seed_mode = RANDOM; } else { - std::cout << "Invalid argument: --seed-mode must be either 'incremental' or 'random'." << std::endl; + std::cout + << "Invalid argument: --seed-mode must be either 'incremental' or 'random'." + << std::endl; } bool debug_mode = vm.count("debug-converter") > 0; @@ -343,13 +327,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) converter_id.output_format = out_format; converter_id.num_inputs = n_inputs; converter_id.num_outputs = n_outputs; - std::cout << "Requested converter format: " << converter_id.to_string() - << std::endl; + std::cout << "Requested converter format: " << converter_id.to_string() << std::endl; uhd::dict<priority_type, converter::sptr> conv_list; if (priorities == "default" or priorities.empty()) { try { - conv_list[prio] = get_converter(converter_id, prio)(); // Can throw a uhd::key_error - } catch(const uhd::key_error &) { + conv_list[prio] = + get_converter(converter_id, prio)(); // Can throw a uhd::key_error + } catch (const uhd::key_error&) { std::cout << "No converters found." << std::endl; return EXIT_FAILURE; } @@ -357,7 +341,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) for (priority_type i = 0; i < max_prio; i++) { try { // get_converter() returns a factory function, execute that immediately: - converter::sptr conv_for_prio = get_converter(converter_id, i)(); // Can throw a uhd::key_error + converter::sptr conv_for_prio = + get_converter(converter_id, i)(); // Can throw a uhd::key_error conv_list[i] = conv_for_prio; } catch (...) { continue; @@ -365,15 +350,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } } else { // Assume that priorities contains a list of prios (e.g. 0,2,3) std::vector<std::string> prios_in_list; - boost::split( - prios_in_list, - priorities, - boost::is_any_of(","), // Split at , - boost::token_compress_on // Avoid empty results + boost::split(prios_in_list, + priorities, + boost::is_any_of(","), // Split at , + boost::token_compress_on // Avoid empty results ); - for(const std::string &this_prio: prios_in_list) { + for (const std::string& this_prio : prios_in_list) { size_t prio_index = boost::lexical_cast<size_t>(this_prio); - converter::sptr conv_for_prio = get_converter(converter_id, prio_index)(); // Can throw a uhd::key_error + converter::sptr conv_for_prio = + get_converter(converter_id, prio_index)(); // Can throw a uhd::key_error conv_list[prio_index] = conv_for_prio; } } @@ -383,25 +368,27 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // First, convert the types to plain types (e.g. sc16_item32_le -> sc16) const std::string in_type = format_to_type(in_format); const std::string out_type = format_to_type(out_format); - const size_t in_size = get_bytes_per_item(in_type); - const size_t out_size = get_bytes_per_item(out_type); + const size_t in_size = get_bytes_per_item(in_type); + const size_t out_size = get_bytes_per_item(out_type); // Create the buffers and fill them with random data & zeros, respectively - std::vector< std::vector<char> > input_buffers(n_inputs, std::vector<char>(in_size * n_samples, 0)); - std::vector< std::vector<char> > output_buffers(n_outputs, std::vector<char>(out_size * n_samples, 0)); + std::vector<std::vector<char>> input_buffers( + n_inputs, std::vector<char>(in_size * n_samples, 0)); + std::vector<std::vector<char>> output_buffers( + n_outputs, std::vector<char>(out_size * n_samples, 0)); init_buffers(input_buffers, in_type, in_size, buf_seed_mode); // Create ref vectors for the converter: - std::vector<const void *> input_buf_refs(n_inputs); - std::vector<void *> output_buf_refs(n_outputs); + std::vector<const void*> input_buf_refs(n_inputs); + std::vector<void*> output_buf_refs(n_outputs); for (size_t i = 0; i < n_inputs; i++) { - input_buf_refs[i] = reinterpret_cast<const void *>(&input_buffers[i][0]); + input_buf_refs[i] = reinterpret_cast<const void*>(&input_buffers[i][0]); } for (size_t i = 0; i < n_outputs; i++) { - output_buf_refs[i] = reinterpret_cast<void *>(&output_buffers[i][0]); + output_buf_refs[i] = reinterpret_cast<void*>(&output_buffers[i][0]); } /// Final configurations to the converter: std::cout << "Configuring converters:" << std::endl; - for(priority_type prio_i: conv_list.keys()) { + for (priority_type prio_i : conv_list.keys()) { std::cout << "* [" << prio_i << "]: "; configure_conv(conv_list[prio_i], in_type, out_type); } @@ -410,38 +397,33 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::cout << "{{{" << std::endl; if (not debug_mode) { std::cout << "prio,duration_ms,avg_duration_ms,n_samples,iterations" << std::endl; - for(priority_type prio_i: conv_list.keys()) { - double duration = run_benchmark( - conv_list[prio_i], - input_buf_refs, - output_buf_refs, - n_samples, - iterations - ); - std::cout << boost::format("%i,%d,%d,%d,%d") - % prio_i - % (duration * 1000) - % (duration * 1000.0 / iterations) - % n_samples - % iterations - << std::endl; + for (priority_type prio_i : conv_list.keys()) { + double duration = run_benchmark(conv_list[prio_i], + input_buf_refs, + output_buf_refs, + n_samples, + iterations); + std::cout << boost::format("%i,%d,%d,%d,%d") % prio_i % (duration * 1000) + % (duration * 1000.0 / iterations) % n_samples % iterations + << std::endl; } } /// Or run debug mode, which runs one conversion and prints the results //// if (debug_mode) { // Only run on the first converter: - run_benchmark( - conv_list[conv_list.keys().at(0)], + run_benchmark(conv_list[conv_list.keys().at(0)], input_buf_refs, output_buf_refs, n_samples, - iterations - ); + iterations); for (size_t i = 0; i < n_samples; i++) { std::cout << item_to_string(input_buf_refs[0], i, in_type, vm.count("hex")) << ";" - << item_to_string(reinterpret_cast< const void * >(output_buf_refs[0]), i, out_type, vm.count("hex")) + << item_to_string(reinterpret_cast<const void*>(output_buf_refs[0]), + i, + out_type, + vm.count("hex")) << std::endl; } } diff --git a/host/utils/fx2_init_eeprom.cpp b/host/utils/fx2_init_eeprom.cpp index 448652faf..e375b27f5 100644 --- a/host/utils/fx2_init_eeprom.cpp +++ b/host/utils/fx2_init_eeprom.cpp @@ -5,31 +5,32 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> +#include "b100_eeprom.h" +#include "usrp1_eeprom.h" #include <uhd/device.hpp> #include <uhd/property_tree.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> -#include <boost/filesystem.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string/predicate.hpp> -#include <iostream> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <fstream> -#include "usrp1_eeprom.h" -#include "b100_eeprom.h" +#include <iostream> #ifdef UHD_PLATFORM_LINUX -#include <unistd.h> // syscall constants -#include <fcntl.h> // O_NONBLOCK -#include <sys/syscall.h> -#include <cerrno> -#include <cstring> // for std::strerror -#endif //UHD_PLATFORM_LINUX +# include <fcntl.h> // O_NONBLOCK +# include <sys/syscall.h> +# include <unistd.h> // syscall constants +# include <cerrno> +# include <cstring> // for std::strerror +#endif // UHD_PLATFORM_LINUX const std::string FX2_VENDOR_ID("0x04b4"); const std::string FX2_PRODUCT_ID("0x8613"); namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ std::string type; std::string image; po::options_description desc("Allowed options"); @@ -47,97 +48,104 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl; return EXIT_FAILURE; } #ifdef UHD_PLATFORM_LINUX - //can't find an uninitialized usrp with this mystery usbtest in the way... + // can't find an uninitialized usrp with this mystery usbtest in the way... std::string module("usbtest"); std::ifstream modules("/proc/modules"); bool module_found = false; std::string module_line; - while(std::getline(modules, module_line) && (!module_found)) { + while (std::getline(modules, module_line) && (!module_found)) { module_found = boost::starts_with(module_line, module); } - if(module_found) { - std::cout << boost::format("Found the '%s' module. Unloading it.\n" ) % module; + if (module_found) { + std::cout << boost::format("Found the '%s' module. Unloading it.\n") % module; int fail = syscall(__NR_delete_module, module.c_str(), O_NONBLOCK); - if(fail) - std::cerr << ( boost::format("Removing the '%s' module failed with error '%s'.\n") % module % std::strerror(errno) ); + if (fail) + std::cerr << (boost::format( + "Removing the '%s' module failed with error '%s'.\n") + % module % std::strerror(errno)); } -#endif //UHD_PLATFORM_LINUX +#endif // UHD_PLATFORM_LINUX - //load the options into the address + // load the options into the address uhd::device_addr_t device_addr; device_addr["type"] = type; - if(vm.count("vid") or vm.count("pid")) { - if(not (vm.count("vid") and vm.count("pid") and vm.count("type"))) { - std::cerr << "ERROR: Must specify vid, pid, and type if specifying any of the two former args" << std::endl; + if (vm.count("vid") or vm.count("pid")) { + if (not(vm.count("vid") and vm.count("pid") and vm.count("type"))) { + std::cerr << "ERROR: Must specify vid, pid, and type if specifying any of " + "the two former args" + << std::endl; } else { - device_addr["vid"] = vm["vid"].as<std::string>(); - device_addr["pid"] = vm["pid"].as<std::string>(); + device_addr["vid"] = vm["vid"].as<std::string>(); + device_addr["pid"] = vm["pid"].as<std::string>(); device_addr["type"] = vm["type"].as<std::string>(); } } else { device_addr["vid"] = FX2_VENDOR_ID; device_addr["pid"] = FX2_PRODUCT_ID; } - if(vm.count("image")) { - //if specified, use external image file - image = vm["image"].as<std::string>(); + if (vm.count("image")) { + // if specified, use external image file + image = vm["image"].as<std::string>(); } else { - //if not specified, use built-ins; requires user to define type - size_t image_len; - unsigned const char* image_data; + // if not specified, use built-ins; requires user to define type + size_t image_len; + unsigned const char* image_data; + + if (!vm.count("type")) { + std::cerr << boost::format("ERROR: Image file not specified and type of " + "device not given. Cannot use built-in images.\n"); + return EXIT_FAILURE; + } - if(!vm.count("type")) { - std::cerr << boost::format("ERROR: Image file not specified and type of device not given. Cannot use built-in images.\n"); - return EXIT_FAILURE; - } - - std::cout << boost::format("Using built-in image for \"%s\".\n") % type; - - if(vm["type"].as<std::string>() == "usrp1") { - image_len = usrp1_eeprom_bin_len; - image_data = usrp1_eeprom_bin; - } else if(vm["type"].as<std::string>() == "b100") { - image_len = b100_eeprom_bin_len; - image_data = b100_eeprom_bin; - } else { - std::cerr << boost::format("ERROR: Unsupported device type \"%s\" specified and no EEPROM image file given.\n") % type; - return EXIT_FAILURE; - } + std::cout << boost::format("Using built-in image for \"%s\".\n") % type; + + if (vm["type"].as<std::string>() == "usrp1") { + image_len = usrp1_eeprom_bin_len; + image_data = usrp1_eeprom_bin; + } else if (vm["type"].as<std::string>() == "b100") { + image_len = b100_eeprom_bin_len; + image_data = b100_eeprom_bin; + } else { + std::cerr << boost::format("ERROR: Unsupported device type \"%s\" specified " + "and no EEPROM image file given.\n") + % type; + return EXIT_FAILURE; + } - //get temporary file name, and write image to that. - image = boost::filesystem::unique_path().string(); - std::ofstream tmp_image(image, std::ofstream::binary); - tmp_image.write((const char*)image_data, image_len); - tmp_image.close(); + // get temporary file name, and write image to that. + image = boost::filesystem::unique_path().string(); + std::ofstream tmp_image(image, std::ofstream::binary); + tmp_image.write((const char*)image_data, image_len); + tmp_image.close(); } - //find and create a control transport to do the writing. + // find and create a control transport to do the writing. uhd::device_addrs_t found_addrs = uhd::device::find(device_addr, uhd::device::USRP); - if (found_addrs.size() == 0){ + if (found_addrs.size() == 0) { std::cerr << "No USRP devices found" << std::endl; return EXIT_FAILURE; } - for (size_t i = 0; i < found_addrs.size(); i++){ + for (size_t i = 0; i < found_addrs.size(); i++) { std::cout << "Writing EEPROM data..." << std::endl; - //uhd::device_addrs_t devs = uhd::device::find(found_addrs[i]); + // uhd::device_addrs_t devs = uhd::device::find(found_addrs[i]); uhd::device::sptr dev = uhd::device::make(found_addrs[i], uhd::device::USRP); uhd::property_tree::sptr tree = dev->get_tree(); tree->access<std::string>("/mboards/0/load_eeprom").set(image); } - //delete temporary image file if we created one - if(!vm.count("image")) { - boost::filesystem::remove(image); + // delete temporary image file if we created one + if (!vm.count("image")) { + boost::filesystem::remove(image); } std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl; diff --git a/host/utils/latency/include/Responder.hpp b/host/utils/latency/include/Responder.hpp index 0d690bcd6..81b5e84f9 100644 --- a/host/utils/latency/include/Responder.hpp +++ b/host/utils/latency/include/Responder.hpp @@ -8,279 +8,299 @@ #ifndef RESPONDER_H #define RESPONDER_H +#include <uhd/usrp/multi_usrp.hpp> #include <curses.h> -#include <map> -#include <ctime> #include <stdint.h> - -#include <uhd/usrp/multi_usrp.hpp> +#include <ctime> +#include <map> using namespace std; class Responder { - public: - enum ReturnCodes +public: + enum ReturnCodes { + RETCODE_OK = 0, + RETCODE_BAD_ARGS = -1, + RETCODE_RUNTIME_ERROR = -2, + RETCODE_UNKNOWN_EXCEPTION = -3, + RETCODE_RECEIVE_TIMEOUT = -4, + RETCODE_RECEIVE_FAILED = -5, + RETCODE_MANUAL_ABORT = -6, + RETCODE_BAD_PACKET = -7, + RETCODE_OVERFLOW = -8 + }; + + struct Options + { + string device_args; + double delay; + double sample_rate; + double trigger_level; + float output_scale; + double response_duration; + double dc_offset_delay; + double init_delay; + double timeout; + size_t samps_per_buff; + size_t samps_per_packet; + double level_calibration_duration; + std::string test_title; + std::string stats_filename; + std::string stats_filename_prefix; + std::string stats_filename_suffix; + double delay_min; + double delay_max; + double delay_step; + double pulse_detection_threshold; + uint64_t test_iterations; + size_t end_test_after_success_count; + size_t skip_iterations; + double simulate_frequency; + double time_mul; + size_t flush_count; + size_t optimize_padding; + double rt_priority; + bool ignore_simulation_check; + bool test_iterations_is_sample_count; + bool skip_eob; + bool adjust_simulation_rate; + bool optimize_simulation_rate; + bool no_stats_file; + bool log_file; + bool batch_mode; + bool skip_if_results_exist; + bool skip_send; + bool combine_eob; + bool pause; + bool realtime; + float invert; + float output_value; + bool no_delay; + bool allow_late_bursts; + + uint64_t level_calibration_count() const { - RETCODE_OK = 0, - RETCODE_BAD_ARGS = -1, - RETCODE_RUNTIME_ERROR = -2, - RETCODE_UNKNOWN_EXCEPTION = -3, - RETCODE_RECEIVE_TIMEOUT = -4, - RETCODE_RECEIVE_FAILED = -5, - RETCODE_MANUAL_ABORT = -6, - RETCODE_BAD_PACKET = -7, - RETCODE_OVERFLOW = -8 - }; - - struct Options - { - string device_args; - double delay; - double sample_rate; - double trigger_level; - float output_scale; - double response_duration; - double dc_offset_delay; - double init_delay; - double timeout; - size_t samps_per_buff; - size_t samps_per_packet; - double level_calibration_duration; - std::string test_title; - std::string stats_filename; - std::string stats_filename_prefix; - std::string stats_filename_suffix; - double delay_min; - double delay_max; - double delay_step; - double pulse_detection_threshold; - uint64_t test_iterations; - size_t end_test_after_success_count; - size_t skip_iterations; - double simulate_frequency; - double time_mul; - size_t flush_count; - size_t optimize_padding; - double rt_priority; - bool ignore_simulation_check; - bool test_iterations_is_sample_count; - bool skip_eob; - bool adjust_simulation_rate; - bool optimize_simulation_rate; - bool no_stats_file; - bool log_file; - bool batch_mode; - bool skip_if_results_exist; - bool skip_send; - bool combine_eob; - bool pause; - bool realtime; - float invert; - float output_value; - bool no_delay; - bool allow_late_bursts; - - uint64_t level_calibration_count() const - { - return (uint64_t)(sample_rate * level_calibration_duration); - } + return (uint64_t)(sample_rate * level_calibration_duration); + } - uint64_t response_length() const - { - return (uint64_t)(sample_rate * response_duration); - } - - uint64_t highest_delay_samples(const double delay) const - { - return (uint64_t)(delay * (double)sample_rate); - } - - uint64_t simulate_duration(const double simulate_frequency) const - { - if(simulate_frequency > 0.0) { - return (uint64_t)((double)sample_rate / simulate_frequency); - } - return 0; - } - }; - - typedef struct Stats + uint64_t response_length() const { - double delay; - uint64_t detected; - uint64_t missed; - uint64_t skipped; - } STATS; + return (uint64_t)(sample_rate * response_duration); + } - typedef std::map<uint64_t,STATS> StatsMap; + uint64_t highest_delay_samples(const double delay) const + { + return (uint64_t)(delay * (double)sample_rate); + } - struct DebugInfo + uint64_t simulate_duration(const double simulate_frequency) const { - time_t start_time; - time_t end_time; - time_t start_time_test; - time_t end_time_test; - time_t first_send_timeout; - }; - Responder(Options& opt); - virtual ~Responder(); - - // Main entry point after constructor. - int run(); - - int get_return_code(){return _return_code;} - - protected: - private: - // These 2 variables are used for ncurses output. - WINDOW* _window; - std::stringstream _ss; - std::stringstream _ss_cerr; - - // struct which holds all arguments as constants settable from outside the class - const Options _opt; - - string _stats_filename; // Specify name of statistics file - string _stats_log_filename; // Specify name for log file. - double _delay; // may be altered in all modes. - size_t _samps_per_packet; // This is one of the options of interest. Find out how well it performs. - double _delay_step; // may be altered in interactive mode - double _simulate_frequency; // updated during automatic test iterations - - // additional attributes - bool _allow_late_bursts; // may be altered in interactive mode - bool _no_delay; // may be altered in interactive mode - - // dependent variables - uint64_t _response_length; - int64_t _init_delay_count; - int64_t _dc_offset_countdown; - int64_t _level_calibration_countdown; - uint64_t _simulate_duration; - uint64_t _original_simulate_duration; - - // these variables store test conditions - uint64_t _num_total_samps; // printed on exit - size_t _overruns; // printed on exit - StatsMap _mapStats; // store results - uint64_t _max_success; // < 0 --> write results to file - int _return_code; - - // Hold USRP, streams and commands - uhd::usrp::multi_usrp::sptr _usrp; - uhd::tx_streamer::sptr _tx_stream; - uhd::rx_streamer::sptr _rx_stream; - uhd::stream_cmd_t _stream_cmd; - - // Keep track of number of timeouts. - uint64_t _timeout_burst_count; - uint64_t _timeout_eob_count; - - // Transmit attributes - float* _pResponse; - - // Control print parameters. - int _y_delay_pos; - int _x_delay_pos; // Remember the cursor position of delay line - uint64_t _last_overrun_count; - - // Hold debug info during test. Will be included in log file. - DebugInfo _dbginfo; - - /* - * Here are the class's member methods. - */ - // These methods are used for ncurses output - void create_ncurses_window(); - void FLUSH_SCREEN(); - void FLUSH_SCREEN_NL(); - - // Variable calculation helpers - inline uint64_t get_response_length(double sample_rate, double response_duration) - {return (uint64_t)(sample_rate * response_duration);} - int calculate_dependent_values(); - - // make sure existing results are not overwritten accidently - bool set_stats_filename(string test_id); - bool check_for_existing_results(); - - // Functions that may cause Responder to finish - void register_stop_signal_handler(); - bool test_finished(size_t success_count); - int test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_test, STATS statsCurrent, size_t success_count); - - // Check if sent burst could be transmitted. - bool tx_burst_is_late(); - - // Handle receiver errors such as overflows. - bool handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps); - - // In interactive mode, handle Responder control and output. - bool handle_interactive_control(); - void print_interactive_msg(std::string msg); - - // calibration important for interactive mode with 2nd USRP connected. - float calibrate_usrp_for_test_run(); - - // Run actual test - void run_test(float threshold = 0.0f ); - - // Detect falling edge - bool get_new_state(uint64_t total_samps, uint64_t simulate_duration, float val, float threshold); - uint64_t detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::complex<float> > &buff, uint64_t trigger_count, size_t num_rx_samps, float threshold, uhd::time_spec_t rx_time); - - // Hold test results till they are printed to a file - void add_stats_to_results(STATS statsCurrent, double delay); - - // Control USRP and necessary streamers - uhd::usrp::multi_usrp::sptr create_usrp_device(); - void set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena); - void stop_usrp_stream(); - uhd::tx_streamer::sptr create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp); - uhd::rx_streamer::sptr create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp); - - // Send burst and handle results. - bool send_tx_burst(uhd::time_spec_t rx_time, size_t n); - void handle_tx_timeout(int burst, int eob); - float* alloc_response_buffer_with_data(uint64_t response_length); - uhd::tx_metadata_t get_tx_metadata(uhd::time_spec_t rx_time, size_t n); - - // Control test parameters - void update_and_print_parameters(const STATS& statsPrev, const double delay); - double get_simulate_frequency(double delay, uint64_t response_length, uint64_t original_simulate_duration); - double get_max_possible_frequency(uint64_t highest_delay_samples, uint64_t response_length); - - // Helper methods to print status during test. - void print_init_test_status(); - void print_test_title(); - void print_usrp_status(); - void print_create_usrp_msg(); - void print_tx_stream_status(); - void print_rx_stream_status(); - void print_test_parameters(); - void print_formatted_delay_line(const uint64_t simulate_duration, const uint64_t old_simulate_duration, const STATS& statsPrev, const double delay, const double simulate_frequency); - void print_overrun_msg(); - void print_error_msg(std::string msg); - void print_timeout_msg(); - void print_final_statistics(); - void print_msg_and_wait(std::string msg); - void print_msg(std::string msg); - - // Safe results of test to file. - void write_statistics_to_file(StatsMap mapStats); - void safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success, int return_code); - void write_log_file(); - - // Write debug info to log file if requested. - void write_debug_info(ofstream& logs); - std::string get_gmtime_string(time_t time); - std::string enum2str(int return_code); - std::vector<std::map<std::string,std::string> > read_eth_info(); - uhd::device_addr_t get_usrp_info(); - std::map<std::string, std::string> get_hw_info(); - std::string get_ip_subnet_addr(std::string ip); + if (simulate_frequency > 0.0) { + return (uint64_t)((double)sample_rate / simulate_frequency); + } + return 0; + } + }; + + typedef struct Stats + { + double delay; + uint64_t detected; + uint64_t missed; + uint64_t skipped; + } STATS; + + typedef std::map<uint64_t, STATS> StatsMap; + + struct DebugInfo + { + time_t start_time; + time_t end_time; + time_t start_time_test; + time_t end_time_test; + time_t first_send_timeout; + }; + Responder(Options& opt); + virtual ~Responder(); + + // Main entry point after constructor. + int run(); + + int get_return_code() + { + return _return_code; + } + +protected: +private: + // These 2 variables are used for ncurses output. + WINDOW* _window; + std::stringstream _ss; + std::stringstream _ss_cerr; + + // struct which holds all arguments as constants settable from outside the class + const Options _opt; + + string _stats_filename; // Specify name of statistics file + string _stats_log_filename; // Specify name for log file. + double _delay; // may be altered in all modes. + size_t _samps_per_packet; // This is one of the options of interest. Find out how well + // it performs. + double _delay_step; // may be altered in interactive mode + double _simulate_frequency; // updated during automatic test iterations + + // additional attributes + bool _allow_late_bursts; // may be altered in interactive mode + bool _no_delay; // may be altered in interactive mode + + // dependent variables + uint64_t _response_length; + int64_t _init_delay_count; + int64_t _dc_offset_countdown; + int64_t _level_calibration_countdown; + uint64_t _simulate_duration; + uint64_t _original_simulate_duration; + + // these variables store test conditions + uint64_t _num_total_samps; // printed on exit + size_t _overruns; // printed on exit + StatsMap _mapStats; // store results + uint64_t _max_success; // < 0 --> write results to file + int _return_code; + + // Hold USRP, streams and commands + uhd::usrp::multi_usrp::sptr _usrp; + uhd::tx_streamer::sptr _tx_stream; + uhd::rx_streamer::sptr _rx_stream; + uhd::stream_cmd_t _stream_cmd; + + // Keep track of number of timeouts. + uint64_t _timeout_burst_count; + uint64_t _timeout_eob_count; + + // Transmit attributes + float* _pResponse; + + // Control print parameters. + int _y_delay_pos; + int _x_delay_pos; // Remember the cursor position of delay line + uint64_t _last_overrun_count; + + // Hold debug info during test. Will be included in log file. + DebugInfo _dbginfo; + + /* + * Here are the class's member methods. + */ + // These methods are used for ncurses output + void create_ncurses_window(); + void FLUSH_SCREEN(); + void FLUSH_SCREEN_NL(); + + // Variable calculation helpers + inline uint64_t get_response_length(double sample_rate, double response_duration) + { + return (uint64_t)(sample_rate * response_duration); + } + int calculate_dependent_values(); + + // make sure existing results are not overwritten accidently + bool set_stats_filename(string test_id); + bool check_for_existing_results(); + + // Functions that may cause Responder to finish + void register_stop_signal_handler(); + bool test_finished(size_t success_count); + int test_step_finished(uint64_t trigger_count, + uint64_t num_total_samps_test, + STATS statsCurrent, + size_t success_count); + + // Check if sent burst could be transmitted. + bool tx_burst_is_late(); + + // Handle receiver errors such as overflows. + bool handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps); + + // In interactive mode, handle Responder control and output. + bool handle_interactive_control(); + void print_interactive_msg(std::string msg); + + // calibration important for interactive mode with 2nd USRP connected. + float calibrate_usrp_for_test_run(); + + // Run actual test + void run_test(float threshold = 0.0f); + + // Detect falling edge + bool get_new_state( + uint64_t total_samps, uint64_t simulate_duration, float val, float threshold); + uint64_t detect_respond_pulse_count(STATS& statsCurrent, + std::vector<std::complex<float>>& buff, + uint64_t trigger_count, + size_t num_rx_samps, + float threshold, + uhd::time_spec_t rx_time); + + // Hold test results till they are printed to a file + void add_stats_to_results(STATS statsCurrent, double delay); + + // Control USRP and necessary streamers + uhd::usrp::multi_usrp::sptr create_usrp_device(); + void set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena); + void stop_usrp_stream(); + uhd::tx_streamer::sptr create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp); + uhd::rx_streamer::sptr create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp); + + // Send burst and handle results. + bool send_tx_burst(uhd::time_spec_t rx_time, size_t n); + void handle_tx_timeout(int burst, int eob); + float* alloc_response_buffer_with_data(uint64_t response_length); + uhd::tx_metadata_t get_tx_metadata(uhd::time_spec_t rx_time, size_t n); + + // Control test parameters + void update_and_print_parameters(const STATS& statsPrev, const double delay); + double get_simulate_frequency( + double delay, uint64_t response_length, uint64_t original_simulate_duration); + double get_max_possible_frequency( + uint64_t highest_delay_samples, uint64_t response_length); + + // Helper methods to print status during test. + void print_init_test_status(); + void print_test_title(); + void print_usrp_status(); + void print_create_usrp_msg(); + void print_tx_stream_status(); + void print_rx_stream_status(); + void print_test_parameters(); + void print_formatted_delay_line(const uint64_t simulate_duration, + const uint64_t old_simulate_duration, + const STATS& statsPrev, + const double delay, + const double simulate_frequency); + void print_overrun_msg(); + void print_error_msg(std::string msg); + void print_timeout_msg(); + void print_final_statistics(); + void print_msg_and_wait(std::string msg); + void print_msg(std::string msg); + + // Safe results of test to file. + void write_statistics_to_file(StatsMap mapStats); + void safe_write_statistics_to_file( + StatsMap mapStats, uint64_t max_success, int return_code); + void write_log_file(); + + // Write debug info to log file if requested. + void write_debug_info(ofstream& logs); + std::string get_gmtime_string(time_t time); + std::string enum2str(int return_code); + std::vector<std::map<std::string, std::string>> read_eth_info(); + uhd::device_addr_t get_usrp_info(); + std::map<std::string, std::string> get_hw_info(); + std::string get_ip_subnet_addr(std::string ip); }; #endif // RESPONDER_H diff --git a/host/utils/latency/lib/Responder.cpp b/host/utils/latency/lib/Responder.cpp index 5597c0fcd..0d7a307dd 100644 --- a/host/utils/latency/lib/Responder.cpp +++ b/host/utils/latency/lib/Responder.cpp @@ -6,60 +6,55 @@ // #include "Responder.hpp" - -#include <iostream> -#include <iomanip> -#include <fstream> +#include <uhd/property_tree.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/thread/condition_variable.hpp> +#include <cmath> #include <complex> #include <csignal> -#include <cmath> +#include <fstream> +#include <iomanip> +#include <iostream> #include <sstream> -#include <boost/format.hpp> -#include <boost/algorithm/string.hpp> -#include <boost/thread/condition_variable.hpp> -#include <boost/filesystem.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/property_tree.hpp> - const std::string _eth_file("eths_info.txt"); // Redirect output to stderr -struct cerr_redirect { - cerr_redirect( std::streambuf * new_buffer ) - : old( std::cerr.rdbuf( new_buffer ) ) - { } +struct cerr_redirect +{ + cerr_redirect(std::streambuf* new_buffer) : old(std::cerr.rdbuf(new_buffer)) {} - ~cerr_redirect( ) { - std::cerr.rdbuf( old ); + ~cerr_redirect() + { + std::cerr.rdbuf(old); } private: - std::streambuf * old; + std::streambuf* old; }; - // Catch keyboard interrupts for clean manual abort static bool s_stop_signal_called = false; -static int s_signal = 0; +static int s_signal = 0; static void sig_int_handler(int signal) { s_stop_signal_called = true; - s_signal = signal; + s_signal = signal; } // member of Responder to register sig int handler -void -Responder::register_stop_signal_handler() +void Responder::register_stop_signal_handler() { std::signal(SIGINT, &sig_int_handler); } // For ncurses. Print everything in stream to screen -void -Responder::FLUSH_SCREEN() +void Responder::FLUSH_SCREEN() { printw(_ss.str().c_str()); refresh(); @@ -67,13 +62,12 @@ Responder::FLUSH_SCREEN() } // Like FLUSH_SCREEN but with new line -void -Responder::FLUSH_SCREEN_NL() +void Responder::FLUSH_SCREEN_NL() { do { int y, x; getyx(_window, y, x); - if (x > 0){ + if (x > 0) { printw("\n"); y++; } @@ -82,33 +76,39 @@ Responder::FLUSH_SCREEN_NL() } // Constructor -Responder::Responder( Options& opt) - : _opt(opt), - _stats_filename(opt.stats_filename), - _delay(opt.delay), - _samps_per_packet(opt.samps_per_packet), - _delay_step(opt.delay_step), - _simulate_frequency(opt.simulate_frequency), - _allow_late_bursts(opt.allow_late_bursts), - _no_delay(opt.no_delay), - //Initialize atributes not given by Options - _num_total_samps(0), // printed on exit - _overruns(0), // printed on exit - _max_success(0), // < 0 --> write results to file - _return_code(RETCODE_OK), - _stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS), - _timeout_burst_count(0), - _timeout_eob_count(0), - _y_delay_pos(-1), - _x_delay_pos(-1), // Remember the cursor position of delay line. +Responder::Responder(Options& opt) + : _opt(opt) + , _stats_filename(opt.stats_filename) + , _delay(opt.delay) + , _samps_per_packet(opt.samps_per_packet) + , _delay_step(opt.delay_step) + , _simulate_frequency(opt.simulate_frequency) + , _allow_late_bursts(opt.allow_late_bursts) + , _no_delay(opt.no_delay) + , + // Initialize atributes not given by Options + _num_total_samps(0) + , // printed on exit + _overruns(0) + , // printed on exit + _max_success(0) + , // < 0 --> write results to file + _return_code(RETCODE_OK) + , _stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS) + , _timeout_burst_count(0) + , _timeout_eob_count(0) + , _y_delay_pos(-1) + , _x_delay_pos(-1) + , // Remember the cursor position of delay line. _last_overrun_count(0) { - time( &_dbginfo.start_time ); // for debugging + time(&_dbginfo.start_time); // for debugging // Disable logging to console uhd::log::set_console_level(uhd::log::off); - if (uhd::set_thread_priority_safe(_opt.rt_priority, _opt.realtime) == false) // try to set realtime scheduling + if (uhd::set_thread_priority_safe(_opt.rt_priority, _opt.realtime) + == false) // try to set realtime scheduling { cerr << "Failed to set real-time" << endl; } @@ -120,16 +120,12 @@ Responder::Responder( Options& opt) create_ncurses_window(); print_create_usrp_msg(); - try - { + try { _usrp = create_usrp_device(); - } - catch (const std::runtime_error& e) - { - print_msg(e.what() ); + } catch (const std::runtime_error& e) { + print_msg(e.what()); _return_code = RETCODE_RUNTIME_ERROR; - } - catch(...){ + } catch (...) { print_msg("unhandled ERROR"); _return_code = RETCODE_UNKNOWN_EXCEPTION; print_msg_and_wait("create USRP device failed!\nPress key to abort test..."); @@ -141,12 +137,10 @@ Responder::Responder( Options& opt) // ensure that filename is set string test_id = _usrp->get_mboard_name(); - if (set_stats_filename(test_id) ) - { + if (set_stats_filename(test_id)) { _return_code = RETCODE_BAD_ARGS; // make sure run() does return! FLUSH_SCREEN(); - if (_opt.batch_mode == false) - { + if (_opt.batch_mode == false) { print_msg_and_wait("Press any key to end..."); } return; @@ -156,20 +150,19 @@ Responder::Responder( Options& opt) register_stop_signal_handler(); } -int -Responder::calculate_dependent_values() +int Responder::calculate_dependent_values() { - _response_length = _opt.response_length(); - _init_delay_count = (int64_t)(_opt.sample_rate * _opt.init_delay); - _dc_offset_countdown = (int64_t)(_opt.sample_rate * _opt.dc_offset_delay); + _response_length = _opt.response_length(); + _init_delay_count = (int64_t)(_opt.sample_rate * _opt.init_delay); + _dc_offset_countdown = (int64_t)(_opt.sample_rate * _opt.dc_offset_delay); _level_calibration_countdown = (int64_t)_opt.level_calibration_count(); - _original_simulate_duration = _simulate_duration = _opt.simulate_duration(_simulate_frequency); + _original_simulate_duration = _simulate_duration = + _opt.simulate_duration(_simulate_frequency); - if (_simulate_duration > 0) - { + if (_simulate_duration > 0) { // Skip settling period and calibration - _init_delay_count = 0; - _dc_offset_countdown = 0; + _init_delay_count = 0; + _dc_offset_countdown = 0; _level_calibration_countdown = 0; double highest_delay = 0.0; @@ -179,70 +172,78 @@ Responder::calculate_dependent_values() highest_delay = _delay; uint64_t highest_delay_samples = _opt.highest_delay_samples(highest_delay); - if ((highest_delay_samples + _response_length + _opt.flush_count) > _simulate_duration) - { - if (_opt.adjust_simulation_rate) // This is now done DURING the simulation based on active delay + if ((highest_delay_samples + _response_length + _opt.flush_count) + > _simulate_duration) { + if (_opt.adjust_simulation_rate) // This is now done DURING the simulation + // based on active delay { //_simulate_frequency = max_possible_rate; - //_simulate_duration = (uint64_t)((double)sample_rate / _simulate_frequency); - } - else - { - cerr << boost::format("Highest delay and response duration will exceed the pulse simulation rate (%ld + %ld > %ld samples)") % highest_delay_samples % _response_length % _simulate_duration << endl; - int max_possible_rate = (int) get_max_possible_frequency(highest_delay_samples, _response_length); - double max_possible_delay = (double)(_simulate_duration - (_response_length + _opt.flush_count)) / (double)_opt.sample_rate; - cerr << boost::format("Simulation rate must be less than %i Hz, or maximum delay must be less than %f s") % max_possible_rate % max_possible_delay << endl; + //_simulate_duration = (uint64_t)((double)sample_rate / + //_simulate_frequency); + } else { + cerr << boost::format( + "Highest delay and response duration will exceed the pulse " + "simulation rate (%ld + %ld > %ld samples)") + % highest_delay_samples % _response_length + % _simulate_duration + << endl; + int max_possible_rate = (int)get_max_possible_frequency( + highest_delay_samples, _response_length); + double max_possible_delay = + (double)(_simulate_duration - (_response_length + _opt.flush_count)) + / (double)_opt.sample_rate; + cerr << boost::format("Simulation rate must be less than %i Hz, or " + "maximum delay must be less than %f s") + % max_possible_rate % max_possible_delay + << endl; if (_opt.ignore_simulation_check == 0) return RETCODE_BAD_ARGS; } } - } - else - { - boost::format fmt("Simulation frequency too high (%f Hz with sample_rate %f Msps)"); - fmt % _simulate_frequency % (_opt.sample_rate/1e6); + } else { + boost::format fmt( + "Simulation frequency too high (%f Hz with sample_rate %f Msps)"); + fmt % _simulate_frequency % (_opt.sample_rate / 1e6); cerr << fmt << endl; return RETCODE_BAD_ARGS; } - if (_opt.test_iterations > 0) // Force certain settings during test mode + if (_opt.test_iterations > 0) // Force certain settings during test mode { - _no_delay = false; + _no_delay = false; _allow_late_bursts = false; - _delay = _opt.delay_min; + _delay = _opt.delay_min; } return RETCODE_OK; // default return code } // print test title to ncurses window -void -Responder::print_test_title() +void Responder::print_test_title() { - if (_opt.test_title.empty() == false) - { + if (_opt.test_title.empty() == false) { std::string title(_opt.test_title); boost::replace_all(title, "%", "%%"); print_msg(title + "\n"); } } -void -Responder::print_usrp_status() +void Responder::print_usrp_status() { std::string msg; - msg += (boost::format("Using device:\n%s\n") % _usrp->get_pp_string() ).str(); - msg += (boost::format("Setting RX rate: %f Msps\n") % (_opt.sample_rate/1e6)).str(); - msg += (boost::format("Actual RX rate: %f Msps\n") % (_usrp->get_rx_rate()/1e6) ).str(); - msg += (boost::format("Setting TX rate: %f Msps\n") % (_opt.sample_rate/1e6) ).str(); - msg += (boost::format("Actual TX rate: %f Msps") % (_usrp->get_tx_rate()/1e6) ).str(); + msg += (boost::format("Using device:\n%s\n") % _usrp->get_pp_string()).str(); + msg += (boost::format("Setting RX rate: %f Msps\n") % (_opt.sample_rate / 1e6)).str(); + msg += (boost::format("Actual RX rate: %f Msps\n") % (_usrp->get_rx_rate() / 1e6)) + .str(); + msg += (boost::format("Setting TX rate: %f Msps\n") % (_opt.sample_rate / 1e6)).str(); + msg += + (boost::format("Actual TX rate: %f Msps") % (_usrp->get_tx_rate() / 1e6)).str(); print_msg(msg); print_tx_stream_status(); print_rx_stream_status(); } -void -Responder::print_test_parameters() +void Responder::print_test_parameters() { // Some status output shoud be printed here! size_t rx_max_num_samps = _rx_stream->get_max_num_samps(); @@ -250,52 +251,58 @@ Responder::print_test_parameters() std::string msg; msg += (boost::format("Samples per buffer: %d\n") % _opt.samps_per_buff).str(); - msg += (boost::format("Maximum number of samples: RX = %d, TX = %d\n") % rx_max_num_samps % tx_max_num_samps).str(); - msg += (boost::format("Response length: %ld samples (%f us)") % _response_length % (_opt.response_duration * 1e6) ).str(); + msg += (boost::format("Maximum number of samples: RX = %d, TX = %d\n") + % rx_max_num_samps % tx_max_num_samps) + .str(); + msg += (boost::format("Response length: %ld samples (%f us)") % _response_length + % (_opt.response_duration * 1e6)) + .str(); if (_simulate_duration > 0) - msg += (boost::format("\nSimulating pulses at %f Hz (every %ld samples)") % _simulate_frequency % _simulate_duration ).str(); + msg += (boost::format("\nSimulating pulses at %f Hz (every %ld samples)") + % _simulate_frequency % _simulate_duration) + .str(); - if (_opt.test_iterations > 0) - { - msg += (boost::format("\nTest coverage: %f -> %f (%f steps)") % _opt.delay_min % _opt.delay_max % _opt.delay_step ).str(); + if (_opt.test_iterations > 0) { + msg += (boost::format("\nTest coverage: %f -> %f (%f steps)") % _opt.delay_min + % _opt.delay_max % _opt.delay_step) + .str(); if (_opt.end_test_after_success_count > 0) - msg += (boost::format("\nTesting will end after %d successful delays") % _opt.end_test_after_success_count ).str(); + msg += (boost::format("\nTesting will end after %d successful delays") + % _opt.end_test_after_success_count) + .str(); } - if ((_dc_offset_countdown == 0) && (_simulate_frequency == 0.0)) - { + if ((_dc_offset_countdown == 0) && (_simulate_frequency == 0.0)) { msg += "\nDC offset disabled"; } print_msg(msg); } -// e.g. B200 doesn't support this command. Check if possible and only set rx_dc_offset if available -void -Responder::set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena) +// e.g. B200 doesn't support this command. Check if possible and only set rx_dc_offset if +// available +void Responder::set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena) { uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // FIXME: Path needs to be build in a programmatic way. - bool dc_offset_exists = tree->exists( uhd::fs_path("/mboards/0/rx_frontends/A/dc_offset") ); - if(dc_offset_exists) - { + bool dc_offset_exists = + tree->exists(uhd::fs_path("/mboards/0/rx_frontends/A/dc_offset")); + if (dc_offset_exists) { usrp->set_rx_dc_offset(ena); } } -void -Responder::print_create_usrp_msg() +void Responder::print_create_usrp_msg() { std::string msg("Creating the USRP device"); if (_opt.device_args.empty() == false) - msg.append( (boost::format(" with args \"%s\"") % _opt.device_args ).str() ); + msg.append((boost::format(" with args \"%s\"") % _opt.device_args).str()); msg.append("..."); print_msg(msg); } -uhd::usrp::multi_usrp::sptr -Responder::create_usrp_device() +uhd::usrp::multi_usrp::sptr Responder::create_usrp_device() { uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(_opt.device_args); usrp->set_rx_rate(_opt.sample_rate); // set the rx sample rate @@ -307,22 +314,19 @@ Responder::create_usrp_device() return usrp; } -uhd::rx_streamer::sptr -Responder::create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp) +uhd::rx_streamer::sptr Responder::create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp) { - uhd::stream_args_t stream_args("fc32"); //complex floats - if (_samps_per_packet > 0) - { + uhd::stream_args_t stream_args("fc32"); // complex floats + if (_samps_per_packet > 0) { stream_args.args["spp"] = str(boost::format("%d") % _samps_per_packet); } uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - _samps_per_packet = rx_stream->get_max_num_samps(); + _samps_per_packet = rx_stream->get_max_num_samps(); return rx_stream; } -void -Responder::print_rx_stream_status() +void Responder::print_rx_stream_status() { std::string msg; msg += (boost::format("Samples per packet set to: %d\n") % _samps_per_packet).str(); @@ -332,27 +336,22 @@ Responder::print_rx_stream_status() print_msg(msg); } -uhd::tx_streamer::sptr -Responder::create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp) +uhd::tx_streamer::sptr Responder::create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp) { - uhd::stream_args_t tx_stream_args("fc32"); //complex floats - if (_allow_late_bursts == false) - { + uhd::stream_args_t tx_stream_args("fc32"); // complex floats + if (_allow_late_bursts == false) { tx_stream_args.args["underflow_policy"] = "next_burst"; } uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(tx_stream_args); return tx_stream; } -void -Responder::print_tx_stream_status() +void Responder::print_tx_stream_status() { std::string msg; - if (_allow_late_bursts == false) - { + if (_allow_late_bursts == false) { msg += "Underflow policy set to drop late bursts"; - } - else + } else msg += "Underflow policy set to allow late bursts"; if (_opt.skip_send) msg += "\nNOT sending bursts"; @@ -362,35 +361,36 @@ Responder::print_tx_stream_status() } // handle transmit timeouts properly -void -Responder::handle_tx_timeout(int burst, int eob) +void Responder::handle_tx_timeout(int burst, int eob) { - if(_timeout_burst_count == 0 && _timeout_eob_count == 0) - time( &_dbginfo.first_send_timeout ); + if (_timeout_burst_count == 0 && _timeout_eob_count == 0) + time(&_dbginfo.first_send_timeout); _timeout_burst_count += burst; _timeout_eob_count += eob; print_timeout_msg(); } -void -Responder::print_timeout_msg() +void Responder::print_timeout_msg() { - move(_y_delay_pos+3, _x_delay_pos); - print_msg( (boost::format("Send timeout, burst_count = %ld\teob_count = %ld\n") % _timeout_burst_count % _timeout_eob_count ).str() ); + move(_y_delay_pos + 3, _x_delay_pos); + print_msg((boost::format("Send timeout, burst_count = %ld\teob_count = %ld\n") + % _timeout_burst_count % _timeout_eob_count) + .str()); } uhd::tx_metadata_t Responder::get_tx_metadata(uhd::time_spec_t rx_time, size_t n) { uhd::tx_metadata_t tx_md; tx_md.start_of_burst = true; - tx_md.end_of_burst = false; + tx_md.end_of_burst = false; if ((_opt.skip_eob == false) && (_opt.combine_eob)) { tx_md.end_of_burst = true; } if (_no_delay == false) { tx_md.has_time_spec = true; - tx_md.time_spec = rx_time + uhd::time_spec_t(0, n, _opt.sample_rate) + uhd::time_spec_t(_delay); + tx_md.time_spec = + rx_time + uhd::time_spec_t(0, n, _opt.sample_rate) + uhd::time_spec_t(_delay); } else { tx_md.has_time_spec = false; } @@ -402,22 +402,25 @@ bool Responder::send_tx_burst(uhd::time_spec_t rx_time, size_t n) if (_opt.skip_send == true) { return false; } - //send a single packet + // send a single packet uhd::tx_metadata_t tx_md = get_tx_metadata(rx_time, n); - const size_t length_to_send = _response_length + (_opt.flush_count - (tx_md.end_of_burst ? 0 : 1)); + const size_t length_to_send = + _response_length + (_opt.flush_count - (tx_md.end_of_burst ? 0 : 1)); - size_t num_tx_samps = _tx_stream->send(_pResponse, length_to_send, tx_md, _opt.timeout); // send pulse! + size_t num_tx_samps = + _tx_stream->send(_pResponse, length_to_send, tx_md, _opt.timeout); // send pulse! if (num_tx_samps < length_to_send) { handle_tx_timeout(1, 0); } if (_opt.skip_eob == false && _opt.combine_eob == false) { tx_md.start_of_burst = false; - tx_md.end_of_burst = true; - tx_md.has_time_spec = false; + tx_md.end_of_burst = true; + tx_md.has_time_spec = false; const size_t eob_length_to_send = 1; - size_t eob_num_tx_samps = _tx_stream->send(&_pResponse[length_to_send], eob_length_to_send, tx_md); // send EOB + size_t eob_num_tx_samps = _tx_stream->send( + &_pResponse[length_to_send], eob_length_to_send, tx_md); // send EOB if (eob_num_tx_samps < eob_length_to_send) { handle_tx_timeout(0, 1); } @@ -427,61 +430,69 @@ bool Responder::send_tx_burst(uhd::time_spec_t rx_time, size_t n) } // ensure that stats_filename is not empty. -bool -Responder::set_stats_filename(string test_id) +bool Responder::set_stats_filename(string test_id) { - if (_stats_filename.empty()) - { + if (_stats_filename.empty()) { string file_friendly_test_id(test_id); boost::replace_all(file_friendly_test_id, " ", "_"); - boost::format fmt = boost::format("%slatency-stats.id_%s-rate_%i-spb_%i-spp_%i%s") % _opt.stats_filename_prefix % file_friendly_test_id % (int)_opt.sample_rate % _opt.samps_per_buff % _samps_per_packet % _opt.stats_filename_suffix; - _stats_filename = str(fmt) + ".txt"; + boost::format fmt = boost::format("%slatency-stats.id_%s-rate_%i-spb_%i-spp_%i%s") + % _opt.stats_filename_prefix % file_friendly_test_id + % (int)_opt.sample_rate % _opt.samps_per_buff + % _samps_per_packet % _opt.stats_filename_suffix; + _stats_filename = str(fmt) + ".txt"; _stats_log_filename = str(fmt) + ".log"; } return check_for_existing_results(); } // Check if results file can be overwritten -bool -Responder::check_for_existing_results() +bool Responder::check_for_existing_results() { bool ex = false; - if ((_opt.skip_if_results_exist) && (boost::filesystem::exists(_stats_filename))) - { - print_msg( (boost::format("Skipping invocation as results file already exists: %s") % _stats_filename).str() ); + if ((_opt.skip_if_results_exist) && (boost::filesystem::exists(_stats_filename))) { + print_msg((boost::format("Skipping invocation as results file already exists: %s") + % _stats_filename) + .str()); ex = true; } return ex; } // Allocate an array with a burst response -float* -Responder::alloc_response_buffer_with_data(uint64_t response_length) // flush_count, output_value, output_scale are const +float* Responder::alloc_response_buffer_with_data( + uint64_t response_length) // flush_count, output_value, output_scale are const { float* pResponse = new float[(response_length + _opt.flush_count) * 2]; for (unsigned int i = 0; i < (response_length * 2); ++i) pResponse[i] = _opt.output_value * _opt.output_scale; - for (unsigned int i = (response_length * 2); i < ((response_length + _opt.flush_count) * 2); ++i) + for (unsigned int i = (response_length * 2); + i < ((response_length + _opt.flush_count) * 2); + ++i) pResponse[i] = 0.0f; return pResponse; } // print test parameters for current delay time -void -Responder::print_formatted_delay_line(const uint64_t simulate_duration, const uint64_t old_simulate_duration, const STATS& statsPrev, const double delay, const double simulate_frequency) +void Responder::print_formatted_delay_line(const uint64_t simulate_duration, + const uint64_t old_simulate_duration, + const STATS& statsPrev, + const double delay, + const double simulate_frequency) { - if(_y_delay_pos < 0 || _x_delay_pos < 0){ // make sure it gets printed to the same position everytime + if (_y_delay_pos < 0 + || _x_delay_pos < 0) { // make sure it gets printed to the same position everytime getyx(_window, _y_delay_pos, _x_delay_pos); } double score = 0.0; if (statsPrev.detected > 0) - score = 100.0 * (double)(statsPrev.detected - statsPrev.missed) / (double)statsPrev.detected; + score = 100.0 * (double)(statsPrev.detected - statsPrev.missed) + / (double)statsPrev.detected; std::string form; boost::format fmt0("Delay now: %.6f (previous delay %.6f scored %.1f%% [%ld / %ld])"); - fmt0 % delay % statsPrev.delay % score % (statsPrev.detected - statsPrev.missed) % statsPrev.detected; + fmt0 % delay % statsPrev.delay % score % (statsPrev.detected - statsPrev.missed) + % statsPrev.detected; form += fmt0.str(); - if (old_simulate_duration != simulate_duration) - { + if (old_simulate_duration != simulate_duration) { boost::format fmt1(" [Simulation rate now: %.1f Hz (%ld samples)]"); fmt1 % simulate_frequency % simulate_duration; form = form + fmt1.str(); @@ -491,8 +502,7 @@ Responder::print_formatted_delay_line(const uint64_t simulate_duration, const ui } // print message and wait for user interaction -void -Responder::print_msg_and_wait(std::string msg) +void Responder::print_msg_and_wait(std::string msg) { msg = "\n" + msg; print_msg(msg); @@ -502,114 +512,103 @@ Responder::print_msg_and_wait(std::string msg) } // print message to ncurses window -void -Responder::print_msg(std::string msg) +void Responder::print_msg(std::string msg) { _ss << msg << endl; FLUSH_SCREEN(); } // Check if error occured during call to receive -bool -Responder::handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps) +bool Responder::handle_rx_errors( + uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps) { // handle errors - if (err == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) - { - std::string msg = (boost::format("Timeout while streaming (received %ld samples)") % _num_total_samps).str(); + if (err == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { + std::string msg = (boost::format("Timeout while streaming (received %ld samples)") + % _num_total_samps) + .str(); print_error_msg(msg); _return_code = RETCODE_RECEIVE_TIMEOUT; return true; - } - else if (err == uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET) - { - std::string msg = (boost::format("Bad packet (received %ld samples)") % _num_total_samps).str(); + } else if (err == uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET) { + std::string msg = + (boost::format("Bad packet (received %ld samples)") % _num_total_samps).str(); print_error_msg(msg); _return_code = RETCODE_BAD_PACKET; return true; - } - else if ((num_rx_samps == 0) && (err == uhd::rx_metadata_t::ERROR_CODE_NONE)) - { + } else if ((num_rx_samps == 0) && (err == uhd::rx_metadata_t::ERROR_CODE_NONE)) { print_error_msg("Received no samples"); _return_code = RETCODE_RECEIVE_FAILED; return true; - } - else if (err == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) - { + } else if (err == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { ++_overruns; print_overrun_msg(); // update overrun info on console. - } - else if (err != uhd::rx_metadata_t::ERROR_CODE_NONE) - { - throw std::runtime_error(str(boost::format( - "Unexpected error code 0x%x" - ) % err)); + } else if (err != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error(str(boost::format("Unexpected error code 0x%x") % err)); } return false; } // print overrun status message. -void -Responder::print_overrun_msg() +void Responder::print_overrun_msg() { - if (_num_total_samps > (_last_overrun_count + (uint64_t)(_opt.sample_rate * 1.0))) - { + if (_num_total_samps > (_last_overrun_count + (uint64_t)(_opt.sample_rate * 1.0))) { int y, x, y_max, x_max; getyx(_window, y, x); getmaxyx(_window, y_max, x_max); - move(y_max-1, 0); - print_msg( (boost::format("Overruns: %d") % _overruns).str() ); + move(y_max - 1, 0); + print_msg((boost::format("Overruns: %d") % _overruns).str()); move(y, x); _last_overrun_count = _num_total_samps; } } // print error message on last line of ncurses window -void -Responder::print_error_msg(std::string msg) +void Responder::print_error_msg(std::string msg) { int y, x, y_max, x_max; getyx(_window, y, x); getmaxyx(_window, y_max, x_max); - move(y_max-2, 0); + move(y_max - 2, 0); clrtoeol(); print_msg(msg); move(y, x); } // calculate simulate frequency -double -Responder::get_simulate_frequency(double delay, uint64_t response_length, uint64_t original_simulate_duration) +double Responder::get_simulate_frequency( + double delay, uint64_t response_length, uint64_t original_simulate_duration) { - double simulate_frequency = _simulate_frequency; + double simulate_frequency = _simulate_frequency; uint64_t highest_delay_samples = _opt.highest_delay_samples(delay); - if ((_opt.optimize_simulation_rate) || - ((highest_delay_samples + response_length + _opt.flush_count) > original_simulate_duration)) - { - simulate_frequency = get_max_possible_frequency(highest_delay_samples, response_length); + if ((_opt.optimize_simulation_rate) + || ((highest_delay_samples + response_length + _opt.flush_count) + > original_simulate_duration)) { + simulate_frequency = + get_max_possible_frequency(highest_delay_samples, response_length); } return simulate_frequency; } // calculate max possible simulate frequency -double -Responder::get_max_possible_frequency(uint64_t highest_delay_samples, uint64_t response_length) // only 2 args, others are all const! +double Responder::get_max_possible_frequency(uint64_t highest_delay_samples, + uint64_t response_length) // only 2 args, others are all const! { - return std::floor((double)_opt.sample_rate / (double)(highest_delay_samples + response_length + _opt.flush_count + _opt.optimize_padding)); + return std::floor((double)_opt.sample_rate + / (double)(highest_delay_samples + response_length + + _opt.flush_count + _opt.optimize_padding)); } // Check if conditions to finish test are met. -bool -Responder::test_finished(size_t success_count) +bool Responder::test_finished(size_t success_count) { - if (success_count == _opt.end_test_after_success_count) - { - print_msg( (boost::format("\nTest complete after %d successes.") % success_count).str() ); + if (success_count == _opt.end_test_after_success_count) { + print_msg( + (boost::format("\nTest complete after %d successes.") % success_count).str()); return true; } - if (((_opt.delay_min <= _opt.delay_max) && (_delay >= _opt.delay_max)) || - ((_opt.delay_min > _opt.delay_max) && (_delay <= _opt.delay_max))) - { + if (((_opt.delay_min <= _opt.delay_max) && (_delay >= _opt.delay_max)) + || ((_opt.delay_min > _opt.delay_max) && (_delay <= _opt.delay_max))) { print_msg("\nTest complete."); return true; } @@ -617,45 +616,38 @@ Responder::test_finished(size_t success_count) } // handle keyboard input in interactive mode -bool -Responder::handle_interactive_control() +bool Responder::handle_interactive_control() { std::string msg = ""; - int c = wgetch(_window); - if (c > -1) - { + int c = wgetch(_window); + if (c > -1) { // UP/DOWN Keys control delay step width - if ((c == KEY_DOWN) || (c == KEY_UP)) - { + if ((c == KEY_DOWN) || (c == KEY_UP)) { double dMag = log10(_delay_step); - int iMag = (int)floor(dMag); + int iMag = (int)floor(dMag); iMag += ((c == KEY_UP) ? 1 : -1); _delay_step = pow(10.0, iMag); - msg += (boost::format("Step: %f") % _delay_step ).str(); + msg += (boost::format("Step: %f") % _delay_step).str(); } // LEFT/RIGHT Keys control absolute delay length - if ((c == KEY_LEFT) || (c == KEY_RIGHT)) - { + if ((c == KEY_LEFT) || (c == KEY_RIGHT)) { double step = _delay_step * ((c == KEY_RIGHT) ? 1 : -1); if ((_delay + step) >= 0.0) _delay += step; msg += (boost::format("Delay: %f") % _delay).str(); } // Enable/disable fixed delay <--> best effort mode - if (c == 'd') - { + if (c == 'd') { _no_delay = !_no_delay; if (_no_delay) msg += "Delay disabled (best effort)"; else msg += (boost::format("Delay: %f") % _delay).str(); - } - else if (c == 'q') // exit test + } else if (c == 'q') // exit test { return true; // signal test to stop - } - else if (c == 'l') // change late burst policy + } else if (c == 'l') // change late burst policy { _allow_late_bursts = !_allow_late_bursts; @@ -670,16 +662,13 @@ Responder::handle_interactive_control() } // print updated interactive control value -void -Responder::print_interactive_msg(std::string msg) +void Responder::print_interactive_msg(std::string msg) { - if(msg != "") - { + if (msg != "") { // move cursor back to beginning of line int y, x; getyx(_window, y, x); - if (x > 0) - { + if (x > 0) { move(y, 0); clrtoeol(); } @@ -689,36 +678,31 @@ Responder::print_interactive_msg(std::string msg) } // check if transmit burst is late -bool -Responder::tx_burst_is_late() +bool Responder::tx_burst_is_late() { uhd::async_metadata_t async_md; - if (_usrp->get_device()->recv_async_msg(async_md, 0)) - { - if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_TIME_ERROR) - { + if (_usrp->get_device()->recv_async_msg(async_md, 0)) { + if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_TIME_ERROR) { return true; } } return false; } -void -Responder::create_ncurses_window() +void Responder::create_ncurses_window() { _window = initscr(); - cbreak(); // Unbuffered key input, except for signals (cf. 'raw') + cbreak(); // Unbuffered key input, except for signals (cf. 'raw') noecho(); nonl(); intrflush(_window, FALSE); - keypad(_window, TRUE); // Enable function keys, arrow keys, ... + keypad(_window, TRUE); // Enable function keys, arrow keys, ... nodelay(_window, 0); timeout(0); } // print all fixed test parameters -void -Responder::print_init_test_status() +void Responder::print_init_test_status() { // Clear the window and write new data. erase(); @@ -740,30 +724,29 @@ Responder::print_init_test_status() } // in interactive mode with second usrp sending bursts. calibrate trigger level -float -Responder::calibrate_usrp_for_test_run() +float Responder::calibrate_usrp_for_test_run() { bool calibration_finished = false; - float threshold = 0.0f; + float threshold = 0.0f; double ave_high = 0, ave_low = 0; int ave_high_count = 0, ave_low_count = 0; - bool level_calibration_stage_2 = false; // 1. stage = rough calibration ; 2. stage = fine calibration + bool level_calibration_stage_2 = + false; // 1. stage = rough calibration ; 2. stage = fine calibration - std::vector<std::complex<float> > buff(_opt.samps_per_buff); - while (not s_stop_signal_called && !calibration_finished && _return_code == RETCODE_OK) - { + std::vector<std::complex<float>> buff(_opt.samps_per_buff); + while ( + not s_stop_signal_called && !calibration_finished && _return_code == RETCODE_OK) { uhd::rx_metadata_t rx_md; - size_t num_rx_samps = _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); + size_t num_rx_samps = + _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); // handle errors - if(handle_rx_errors(rx_md.error_code, num_rx_samps) ) - { + if (handle_rx_errors(rx_md.error_code, num_rx_samps)) { break; } // Wait for USRP for DC offset calibration - if (_dc_offset_countdown > 0) - { + if (_dc_offset_countdown > 0) { _dc_offset_countdown -= (int64_t)num_rx_samps; if (_dc_offset_countdown > 0) continue; @@ -772,8 +755,7 @@ Responder::calibrate_usrp_for_test_run() } // Wait for certain time to minimize POWER UP effects - if (_init_delay_count > 0) - { + if (_init_delay_count > 0) { _init_delay_count -= (int64_t)num_rx_samps; if (_init_delay_count > 0) continue; @@ -782,48 +764,35 @@ Responder::calibrate_usrp_for_test_run() //////////////////////////////////////////////////////////// // detect falling edges and calibrate detection values - if (_level_calibration_countdown > 0) - { - if (level_calibration_stage_2 == false) - { + if (_level_calibration_countdown > 0) { + if (level_calibration_stage_2 == false) { float average = 0.0f; for (size_t n = 0; n < num_rx_samps; n++) average += buff[n].real() * _opt.invert; average /= (float)num_rx_samps; - if (ave_low_count == 0) - { + if (ave_low_count == 0) { ave_low = average; ++ave_low_count; - } - else if (average < ave_low) - { + } else if (average < ave_low) { ave_low = average; ++ave_low_count; } - if (ave_high_count == 0) - { + if (ave_high_count == 0) { ave_high = average; ++ave_high_count; - } - else if (average > ave_high) - { + } else if (average > ave_high) { ave_high = average; ++ave_high_count; } - } - else { - for (size_t n = 0; n < num_rx_samps; n++) - { + } else { + for (size_t n = 0; n < num_rx_samps; n++) { float f = buff[n].real() * _opt.invert; - if (f >= threshold) - { + if (f >= threshold) { ave_high += f; ave_high_count++; - } - else - { + } else { ave_low += f; ave_low_count++; } @@ -832,43 +801,51 @@ Responder::calibrate_usrp_for_test_run() _level_calibration_countdown -= (int64_t)num_rx_samps; - if (_level_calibration_countdown <= 0) - { - if (level_calibration_stage_2 == false) - { - level_calibration_stage_2 = true; + if (_level_calibration_countdown <= 0) { + if (level_calibration_stage_2 == false) { + level_calibration_stage_2 = true; _level_calibration_countdown = _opt.level_calibration_count(); - threshold = ave_low + ((ave_high - ave_low) / 2.0); - print_msg( (boost::format("Phase #1: Ave low: %.3f (#%d), ave high: %.3f (#%d), threshold: %.3f") % ave_low % ave_low_count % ave_high % ave_high_count % threshold).str() ); + threshold = ave_low + ((ave_high - ave_low) / 2.0); + print_msg((boost::format("Phase #1: Ave low: %.3f (#%d), ave high: " + "%.3f (#%d), threshold: %.3f") + % ave_low % ave_low_count % ave_high % ave_high_count + % threshold) + .str()); ave_low_count = ave_high_count = 0; ave_low = ave_high = 0.0f; continue; - } - else - { + } else { ave_low /= (double)ave_low_count; ave_high /= (double)ave_high_count; threshold = ave_low + ((ave_high - ave_low) * _opt.trigger_level); - print_msg( (boost::format("Phase #2: Ave low: %.3f (#%d), ave high: %.3f (#%d), threshold: %.3f\n") % ave_low % ave_low_count % ave_high % ave_high_count % threshold).str() ); - - _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; + print_msg((boost::format("Phase #2: Ave low: %.3f (#%d), ave high: " + "%.3f (#%d), threshold: %.3f\n") + % ave_low % ave_low_count % ave_high % ave_high_count + % threshold) + .str()); + + _stream_cmd.stream_mode = + uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); double diff = std::abs(ave_high - ave_low); - if (diff < _opt.pulse_detection_threshold) - { + if (diff < _opt.pulse_detection_threshold) { _return_code = RETCODE_BAD_ARGS; - print_error_msg( (boost::format("Did not detect any pulses (difference %.6f < detection threshold %.6f)") % diff % _opt.pulse_detection_threshold).str() ); + print_error_msg( + (boost::format("Did not detect any pulses (difference %.6f < " + "detection threshold %.6f)") + % diff % _opt.pulse_detection_threshold) + .str()); break; } - _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + _stream_cmd.stream_mode = + uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); } - } - else + } else continue; } // calibration finished calibration_finished = true; @@ -877,86 +854,82 @@ Responder::calibrate_usrp_for_test_run() } // try to stop USRP properly after tests -void -Responder::stop_usrp_stream() +void Responder::stop_usrp_stream() { - try - { - if (_usrp) - { + try { + if (_usrp) { _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; - _stream_cmd.stream_now = true; + _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); } - } - catch (...) - { + } catch (...) { // } } // after each delay length update test parameters and print them -void -Responder::update_and_print_parameters(const STATS& statsPrev, const double delay) +void Responder::update_and_print_parameters(const STATS& statsPrev, const double delay) { uint64_t old_simulate_duration = _simulate_duration; - _simulate_frequency = get_simulate_frequency(delay, _response_length, _original_simulate_duration); + _simulate_frequency = + get_simulate_frequency(delay, _response_length, _original_simulate_duration); _simulate_duration = _opt.simulate_duration(_simulate_frequency); - print_formatted_delay_line(_simulate_duration, old_simulate_duration, statsPrev, delay, _simulate_frequency); + print_formatted_delay_line( + _simulate_duration, old_simulate_duration, statsPrev, delay, _simulate_frequency); _timeout_burst_count = 0; - _timeout_eob_count = 0; + _timeout_eob_count = 0; } // detect or simulate burst level. -bool -Responder::get_new_state(uint64_t total_samps, uint64_t simulate_duration, float val, float threshold) +bool Responder::get_new_state( + uint64_t total_samps, uint64_t simulate_duration, float val, float threshold) { bool new_state = false; if (simulate_duration > 0) // only simulated input bursts! new_state = (((total_samps) % simulate_duration) == 0); else - new_state = (val >= threshold); // TODO: Just measure difference in fall + new_state = (val >= threshold); // TODO: Just measure difference in fall return new_state; } // detect a pulse, respond to it and count number of pulses. // statsCurrent holds parameters. -uint64_t -Responder::detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::complex<float> > &buff, uint64_t trigger_count, size_t num_rx_samps, float threshold, uhd::time_spec_t rx_time) +uint64_t Responder::detect_respond_pulse_count(STATS& statsCurrent, + std::vector<std::complex<float>>& buff, + uint64_t trigger_count, + size_t num_rx_samps, + float threshold, + uhd::time_spec_t rx_time) { // buff, threshold bool input_state = false; - for (size_t n = 0; n < num_rx_samps; n++) - { + for (size_t n = 0; n < num_rx_samps; n++) { float f = buff[n].real() * _opt.invert; - bool new_state = get_new_state(_num_total_samps + n, _simulate_duration, f, threshold); + bool new_state = + get_new_state(_num_total_samps + n, _simulate_duration, f, threshold); if ((new_state == false) && (input_state)) // == falling_edge { trigger_count++; statsCurrent.detected++; - if ((_opt.test_iterations > 0) - && (_opt.skip_iterations > 0) - && (statsCurrent.skipped == 0) - && (_opt.skip_iterations == statsCurrent.detected)) - { + if ((_opt.test_iterations > 0) && (_opt.skip_iterations > 0) + && (statsCurrent.skipped == 0) + && (_opt.skip_iterations == statsCurrent.detected)) { memset(&statsCurrent, 0x00, sizeof(STATS)); - statsCurrent.delay = _delay; + statsCurrent.delay = _delay; statsCurrent.detected = 1; - statsCurrent.skipped = _opt.skip_iterations; + statsCurrent.skipped = _opt.skip_iterations; trigger_count = 1; } - if( !send_tx_burst(rx_time, n) ) - { + if (!send_tx_burst(rx_time, n)) { statsCurrent.missed++; } - if(tx_burst_is_late() ) - { + if (tx_burst_is_late()) { statsCurrent.missed++; } } @@ -967,34 +940,33 @@ Responder::detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::comp } // this is the actual "work" function. All the fun happens here -void -Responder::run_test(float threshold) +void Responder::run_test(float threshold) { STATS statsCurrent; //, statsPrev; memset(&statsCurrent, 0x00, sizeof(STATS)); - if (_opt.test_iterations > 0) - { + if (_opt.test_iterations > 0) { update_and_print_parameters(statsCurrent, _delay); statsCurrent.delay = _opt.delay_min; } /////////////////////////////////////////////////////////////////////////// - uint64_t trigger_count = 0; - size_t success_count = 0; + uint64_t trigger_count = 0; + size_t success_count = 0; uint64_t num_total_samps_test = 0; - std::vector<std::complex<float> > buff(_opt.samps_per_buff); - while (not s_stop_signal_called && _return_code == RETCODE_OK) - { + std::vector<std::complex<float>> buff(_opt.samps_per_buff); + while (not s_stop_signal_called && _return_code == RETCODE_OK) { // get samples from rx stream. uhd::rx_metadata_t rx_md; - size_t num_rx_samps = _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); + size_t num_rx_samps = + _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); // handle errors - if(handle_rx_errors(rx_md.error_code, num_rx_samps) ) - { + if (handle_rx_errors(rx_md.error_code, num_rx_samps)) { break; } - // detect falling edges, send respond pulse and check if response could be sent in time - trigger_count = detect_respond_pulse_count(statsCurrent, buff, trigger_count, num_rx_samps, threshold, rx_md.time_spec); + // detect falling edges, send respond pulse and check if response could be sent in + // time + trigger_count = detect_respond_pulse_count( + statsCurrent, buff, trigger_count, num_rx_samps, threshold, rx_md.time_spec); // increase counters for single test and overall test samples count. _num_total_samps += num_rx_samps; @@ -1003,40 +975,47 @@ Responder::run_test(float threshold) // control section for interactive mode if (_opt.test_iterations == 0) // == "interactive' { - if(handle_interactive_control() ) + if (handle_interactive_control()) break; } // control section for test mode if (_opt.test_iterations > 0) // == test mode / batch-mode { - int step_return = test_step_finished(trigger_count, num_total_samps_test, statsCurrent, success_count); - if(step_return == -2) // == test is finished with all desired delay steps + int step_return = test_step_finished( + trigger_count, num_total_samps_test, statsCurrent, success_count); + if (step_return == -2) // == test is finished with all desired delay steps break; - else if(step_return == -1) // just continue test + else if (step_return == -1) // just continue test continue; else // test with one delay is finished { - success_count = (size_t) step_return; - trigger_count = 0; + success_count = (size_t)step_return; + trigger_count = 0; num_total_samps_test = 0; - memset(&statsCurrent, 0x00, sizeof(STATS)); // reset current stats for next test iteration + memset(&statsCurrent, + 0x00, + sizeof(STATS)); // reset current stats for next test iteration statsCurrent.delay = _delay; } } // end test mode control section - }// exit outer loop after stop signal is called, test is finished or other break condition is met + } // exit outer loop after stop signal is called, test is finished or other break + // condition is met if (s_stop_signal_called) _return_code = RETCODE_MANUAL_ABORT; } // check if test with one specific delay is finished -int -Responder::test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_test, STATS statsCurrent, size_t success_count) +int Responder::test_step_finished(uint64_t trigger_count, + uint64_t num_total_samps_test, + STATS statsCurrent, + size_t success_count) { - if ( ((_opt.test_iterations_is_sample_count == false) && (trigger_count >= _opt.test_iterations)) || - ((_opt.test_iterations_is_sample_count) && (num_total_samps_test > _opt.test_iterations)) ) - { + if (((_opt.test_iterations_is_sample_count == false) + && (trigger_count >= _opt.test_iterations)) + || ((_opt.test_iterations_is_sample_count) + && (num_total_samps_test > _opt.test_iterations))) { add_stats_to_results(statsCurrent, _delay); if (statsCurrent.missed == 0) // == NO late bursts @@ -1044,7 +1023,7 @@ Responder::test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_t else success_count = 0; - if(test_finished(success_count) ) + if (test_finished(success_count)) return -2; // test is completely finished _delay += _delay_step; // increase delay by one step @@ -1056,58 +1035,50 @@ Responder::test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_t } // save test results -void -Responder::add_stats_to_results(STATS statsCurrent, double delay) +void Responder::add_stats_to_results(STATS statsCurrent, double delay) { - _max_success = max(_max_success, (statsCurrent.detected - statsCurrent.missed)); // > 0 --> save results - uint64_t key = (uint64_t)(delay * 1e6); + _max_success = max(_max_success, + (statsCurrent.detected - statsCurrent.missed)); // > 0 --> save results + uint64_t key = (uint64_t)(delay * 1e6); _mapStats[key] = statsCurrent; } // run tests and handle errors -int -Responder::run() +int Responder::run() { if (_return_code != RETCODE_OK) return _return_code; if (_opt.pause) print_msg_and_wait("Press any key to begin..."); - time( &_dbginfo.start_time_test ); + time(&_dbginfo.start_time_test); // Put some info about the test on the console print_init_test_status(); try { - //setup streaming + // setup streaming _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - _stream_cmd.stream_now = true; + _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); - if( !_opt.batch_mode ){ + if (!_opt.batch_mode) { float threshold = calibrate_usrp_for_test_run(); - if (_return_code != RETCODE_OK) - { + if (_return_code != RETCODE_OK) { return _return_code; } run_test(threshold); - } - else - { + } else { run_test(); } - } - catch (const std::runtime_error& e) - { - print_msg(e.what() ); + } catch (const std::runtime_error& e) { + print_msg(e.what()); _return_code = RETCODE_RUNTIME_ERROR; - } - catch (...) - { + } catch (...) { print_msg("Unhandled exception"); _return_code = RETCODE_UNKNOWN_EXCEPTION; } stop_usrp_stream(); - time( &_dbginfo.end_time_test ); + time(&_dbginfo.end_time_test); return (_return_code < 0 ? _return_code : _overruns); } @@ -1116,8 +1087,7 @@ Responder::run() */ // This method should print statistics after ncurses endwin. -void -Responder::print_final_statistics() +void Responder::print_final_statistics() { cout << boost::format("Received %ld samples during test run") % _num_total_samps; if (_overruns > 0) @@ -1126,29 +1096,30 @@ Responder::print_final_statistics() } // safe test results to a log file if enabled -void -Responder::write_log_file() +void Responder::write_log_file() { - try - { - if(_opt.log_file){ + try { + if (_opt.log_file) { std::map<std::string, std::string> hw_info = get_hw_info(); ofstream logs(_stats_log_filename.c_str()); logs << boost::format("title=%s") % _opt.test_title << endl; - logs << boost::format("device=%s") % _usrp->get_mboard_name() << endl; + logs << boost::format("device=%s") % _usrp->get_mboard_name() << endl; logs << boost::format("device_args=%s") % _opt.device_args << endl; - logs << boost::format("type=%s") % hw_info["type"] << endl; - if (hw_info.size() > 0) - { - logs << boost::format("usrp_addr=%s") % hw_info["usrp_addr"] << endl; - logs << boost::format("usrp_name=%s") % hw_info["name"] << endl; - logs << boost::format("serial=%s") % hw_info["serial"] << endl; - logs << boost::format("host_interface=%s") % hw_info["interface"] << endl; - logs << boost::format("host_addr=%s") % hw_info["host_addr"] << endl; - logs << boost::format("host_mac=%s") % hw_info["mac"] << endl; - logs << boost::format("host_vendor=%s (id=%s)") % hw_info["vendor"] % hw_info["vendor_id"] << endl; - logs << boost::format("host_device=%s (id=%s)") % hw_info["device"] % hw_info["device_id"] << endl; + logs << boost::format("type=%s") % hw_info["type"] << endl; + if (hw_info.size() > 0) { + logs << boost::format("usrp_addr=%s") % hw_info["usrp_addr"] << endl; + logs << boost::format("usrp_name=%s") % hw_info["name"] << endl; + logs << boost::format("serial=%s") % hw_info["serial"] << endl; + logs << boost::format("host_interface=%s") % hw_info["interface"] << endl; + logs << boost::format("host_addr=%s") % hw_info["host_addr"] << endl; + logs << boost::format("host_mac=%s") % hw_info["mac"] << endl; + logs << boost::format("host_vendor=%s (id=%s)") % hw_info["vendor"] + % hw_info["vendor_id"] + << endl; + logs << boost::format("host_device=%s (id=%s)") % hw_info["device"] + % hw_info["device_id"] + << endl; } logs << boost::format("sample_rate=%f") % _opt.sample_rate << endl; logs << boost::format("samps_per_buff=%i") % _opt.samps_per_buff << endl; @@ -1158,97 +1129,113 @@ Responder::write_log_file() logs << boost::format("delay_step=%f") % _delay_step << endl; logs << boost::format("delay=%f") % _delay << endl; logs << boost::format("init_delay=%f") % _opt.init_delay << endl; - logs << boost::format("response_duration=%f") % _opt.response_duration << endl; + logs << boost::format("response_duration=%f") % _opt.response_duration + << endl; logs << boost::format("response_length=%ld") % _response_length << endl; logs << boost::format("timeout=%f") % _opt.timeout << endl; - logs << boost::format("timeout_burst_count=%ld") % _timeout_burst_count << endl; + logs << boost::format("timeout_burst_count=%ld") % _timeout_burst_count + << endl; logs << boost::format("timeout_eob_count=%f") % _timeout_eob_count << endl; - logs << boost::format("allow_late_bursts=%s") % (_allow_late_bursts ? "yes" : "no") << endl; + logs << boost::format("allow_late_bursts=%s") + % (_allow_late_bursts ? "yes" : "no") + << endl; logs << boost::format("skip_eob=%s") % (_opt.skip_eob ? "yes" : "no") << endl; - logs << boost::format("combine_eob=%s") % (_opt.combine_eob ? "yes" : "no") << endl; - logs << boost::format("skip_send=%s") % (_opt.skip_send ? "yes" : "no") << endl; + logs << boost::format("combine_eob=%s") % (_opt.combine_eob ? "yes" : "no") + << endl; + logs << boost::format("skip_send=%s") % (_opt.skip_send ? "yes" : "no") + << endl; logs << boost::format("no_delay=%s") % (_no_delay ? "yes" : "no") << endl; logs << boost::format("simulate_frequency=%f") % _simulate_frequency << endl; logs << boost::format("simulate_duration=%ld") % _simulate_duration << endl; - logs << boost::format("original_simulate_duration=%ld") % _original_simulate_duration << endl; + logs << boost::format("original_simulate_duration=%ld") + % _original_simulate_duration + << endl; logs << boost::format("realtime=%s") % (_opt.realtime ? "yes" : "no") << endl; logs << boost::format("rt_priority=%f") % _opt.rt_priority << endl; logs << boost::format("test_iterations=%ld") % _opt.test_iterations << endl; - logs << boost::format("end_test_after_success_count=%i") % _opt.end_test_after_success_count << endl; + logs << boost::format("end_test_after_success_count=%i") + % _opt.end_test_after_success_count + << endl; logs << boost::format("skip_iterations=%i") % _opt.skip_iterations << endl; logs << boost::format("overruns=%i") % _overruns << endl; logs << boost::format("num_total_samps=%ld") % _num_total_samps << endl; - logs << boost::format("return_code=%i\t(%s)") % _return_code % enum2str(_return_code) << endl; + logs << boost::format("return_code=%i\t(%s)") % _return_code + % enum2str(_return_code) + << endl; logs << endl; write_debug_info(logs); - } - } - catch(...) - { + } catch (...) { cerr << "Failed to write log file to: " << _stats_log_filename << endl; } } // write debug info to log file -void -Responder::write_debug_info(ofstream& logs) +void Responder::write_debug_info(ofstream& logs) { logs << endl << "%% DEBUG INFO %%" << endl; - logs << boost::format("dbg_time_start=%s") % get_gmtime_string(_dbginfo.start_time) << endl; - logs << boost::format("dbg_time_end=%s") % get_gmtime_string(_dbginfo.end_time) << endl; - logs << boost::format("dbg_time_duration=%d") % difftime( _dbginfo.end_time, _dbginfo.start_time ) << endl; - logs << boost::format("dbg_time_start_test=%s") % get_gmtime_string(_dbginfo.start_time_test) << endl; - logs << boost::format("dbg_time_end_test=%s") % get_gmtime_string(_dbginfo.end_time_test) << endl; - logs << boost::format("dbg_time_duration_test=%d") % difftime( _dbginfo.end_time_test, _dbginfo.start_time_test ) << endl; - logs << boost::format("dbg_time_first_send_timeout=%s") % get_gmtime_string(_dbginfo.first_send_timeout) << endl; + logs << boost::format("dbg_time_start=%s") % get_gmtime_string(_dbginfo.start_time) + << endl; + logs << boost::format("dbg_time_end=%s") % get_gmtime_string(_dbginfo.end_time) + << endl; + logs << boost::format("dbg_time_duration=%d") + % difftime(_dbginfo.end_time, _dbginfo.start_time) + << endl; + logs << boost::format("dbg_time_start_test=%s") + % get_gmtime_string(_dbginfo.start_time_test) + << endl; + logs << boost::format("dbg_time_end_test=%s") + % get_gmtime_string(_dbginfo.end_time_test) + << endl; + logs << boost::format("dbg_time_duration_test=%d") + % difftime(_dbginfo.end_time_test, _dbginfo.start_time_test) + << endl; + logs << boost::format("dbg_time_first_send_timeout=%s") + % get_gmtime_string(_dbginfo.first_send_timeout) + << endl; } // convert a time string to desired format -std::string -Responder::get_gmtime_string(time_t time) +std::string Responder::get_gmtime_string(time_t time) { tm* ftm; - ftm = gmtime( &time ); + ftm = gmtime(&time); std::string strtime; - strtime.append( (boost::format("%i") % (ftm->tm_year+1900) ).str() ); - strtime.append( (boost::format("-%02i") % ftm->tm_mon).str() ); - strtime.append( (boost::format("-%02i") % ftm->tm_mday).str() ); - strtime.append( (boost::format("-%02i") % ((ftm->tm_hour)) ).str() ); - strtime.append( (boost::format(":%02i") % ftm->tm_min).str() ); - strtime.append( (boost::format(":%02i") % ftm->tm_sec).str() ); + strtime.append((boost::format("%i") % (ftm->tm_year + 1900)).str()); + strtime.append((boost::format("-%02i") % ftm->tm_mon).str()); + strtime.append((boost::format("-%02i") % ftm->tm_mday).str()); + strtime.append((boost::format("-%02i") % ((ftm->tm_hour))).str()); + strtime.append((boost::format(":%02i") % ftm->tm_min).str()); + strtime.append((boost::format(":%02i") % ftm->tm_sec).str()); return strtime; } // read hardware info from file if available to include it in log file -std::map<std::string, std::string> -Responder::get_hw_info() +std::map<std::string, std::string> Responder::get_hw_info() { std::map<std::string, std::string> result; - std::vector<std::map<std::string,std::string> > eths = read_eth_info(); - if(eths.empty()){ + std::vector<std::map<std::string, std::string>> eths = read_eth_info(); + if (eths.empty()) { return result; } uhd::device_addr_t usrp_info = get_usrp_info(); - std::string uaddr = get_ip_subnet_addr(usrp_info["addr"]); + std::string uaddr = get_ip_subnet_addr(usrp_info["addr"]); - for(unsigned int i = 0 ; i < eths.size() ; i++ ) - { - if(get_ip_subnet_addr(eths[i]["addr"]) == uaddr) - { - result["type"] = usrp_info["type"]; + for (unsigned int i = 0; i < eths.size(); i++) { + if (get_ip_subnet_addr(eths[i]["addr"]) == uaddr) { + result["type"] = usrp_info["type"]; result["usrp_addr"] = usrp_info["addr"]; - result["name"] = usrp_info["name"]; - result["serial"] = usrp_info["serial"]; + result["name"] = usrp_info["name"]; + result["serial"] = usrp_info["serial"]; result["interface"] = eths[i]["interface"]; result["host_addr"] = eths[i]["addr"]; - result["mac"] = eths[i]["mac"]; - result["vendor"] = eths[i]["vendor"]; + result["mac"] = eths[i]["mac"]; + result["vendor"] = eths[i]["vendor"]; result["vendor_id"] = eths[i]["vendor_id"]; - result["device"] = eths[i]["device"]; + result["device"] = eths[i]["device"]; result["device_id"] = eths[i]["device_id"]; break; // Use first item found. Imitate device discovery. } @@ -1258,138 +1245,124 @@ Responder::get_hw_info() } // subnet used to identify used network interface -std::string -Responder::get_ip_subnet_addr(std::string ip) +std::string Responder::get_ip_subnet_addr(std::string ip) { return ip.substr(0, ip.rfind(".") + 1); } // get network interface info from file (should include all available interfaces) -std::vector<std::map<std::string,std::string> > -Responder::read_eth_info() +std::vector<std::map<std::string, std::string>> Responder::read_eth_info() { const std::string eth_file(_eth_file); - std::vector<std::map<std::string,std::string> > eths; - try - { + std::vector<std::map<std::string, std::string>> eths; + try { ifstream eth_info(eth_file.c_str()); - if(!eth_info.is_open()){ + if (!eth_info.is_open()) { return eths; } const int len = 256; char cline[len]; - for(; !eth_info.eof() ;) - { + for (; !eth_info.eof();) { eth_info.getline(cline, len); std::string line(cline); - if(line.find("## ETH Interface") != std::string::npos) - { + if (line.find("## ETH Interface") != std::string::npos) { eth_info.getline(cline, len); std::string eth(cline); -// cout << "interface=" << eth << endl; - std::map<std::string,std::string> iface; + // cout << "interface=" << eth << endl; + std::map<std::string, std::string> iface; iface["interface"] = eth; eths.push_back(iface); } const std::string ipstr("\tip "); - if(line.find(ipstr) != std::string::npos) - { - std::string ip( line.replace(line.begin(), line.begin()+ipstr.length(), "") ); -// cout << "ip=" << ip << endl; + if (line.find(ipstr) != std::string::npos) { + std::string ip( + line.replace(line.begin(), line.begin() + ipstr.length(), "")); + // cout << "ip=" << ip << endl; eths.back()["addr"] = ip; } const std::string macstr("\tmac "); - if(line.find(macstr) != std::string::npos) - { - std::string mac( line.replace(line.begin(), line.begin()+macstr.length(), "") ); -// cout << "mac=" << mac << endl; + if (line.find(macstr) != std::string::npos) { + std::string mac( + line.replace(line.begin(), line.begin() + macstr.length(), "")); + // cout << "mac=" << mac << endl; eths.back()["mac"] = mac; } const std::string vstr("\t\tvendor "); - if(line.find(vstr) != std::string::npos) - { - std::string vendor( line.replace(line.begin(), line.begin()+vstr.length(), "") ); - std::string vid( vendor.substr(0,6) ); + if (line.find(vstr) != std::string::npos) { + std::string vendor( + line.replace(line.begin(), line.begin() + vstr.length(), "")); + std::string vid(vendor.substr(0, 6)); vendor.replace(0, 7, ""); -// cout << "id=" << vid << endl; -// cout << "vendor=" << vendor << endl; - eths.back()["vendor"] = vendor; + // cout << "id=" << vid << endl; + // cout << "vendor=" << vendor << endl; + eths.back()["vendor"] = vendor; eths.back()["vendor_id"] = vid; } const std::string dstr("\t\tdevice "); - if(line.find(dstr) != std::string::npos) - { - std::string device( line.replace(line.begin(), line.begin()+dstr.length(), "") ); - std::string did( device.substr(0,6) ); + if (line.find(dstr) != std::string::npos) { + std::string device( + line.replace(line.begin(), line.begin() + dstr.length(), "")); + std::string did(device.substr(0, 6)); device.replace(0, 7, ""); -// cout << "id=" << did << endl; -// cout << "device=" << device << endl; - eths.back()["device"] = device; + // cout << "id=" << did << endl; + // cout << "device=" << device << endl; + eths.back()["device"] = device; eths.back()["device_id"] = did; } } - } - catch(...) - { + } catch (...) { // nothing in yet } return eths; } // get info on used USRP -uhd::device_addr_t -Responder::get_usrp_info() +uhd::device_addr_t Responder::get_usrp_info() { uhd::device_addrs_t device_addrs = uhd::device::find(_opt.device_args); - uhd::device_addr_t device_addr = device_addrs[0]; + uhd::device_addr_t device_addr = device_addrs[0]; return device_addr; } // write statistics of test run to file -void -Responder::write_statistics_to_file(StatsMap mapStats) +void Responder::write_statistics_to_file(StatsMap mapStats) { - try - { + try { ofstream results(_stats_filename.c_str()); - for (StatsMap::iterator it = mapStats.begin(); it != mapStats.end(); ++it) - { + for (StatsMap::iterator it = mapStats.begin(); it != mapStats.end(); ++it) { STATS& stats = it->second; - double d = 0.0; + double d = 0.0; if (stats.detected > 0) d = 1.0 - ((double)stats.missed / (double)stats.detected); - cout << "\t" << setprecision(6) << stats.delay << "\t\t" << setprecision(6) << d << endl; + cout << "\t" << setprecision(6) << stats.delay << "\t\t" << setprecision(6) + << d << endl; - results << (stats.delay * _opt.time_mul) << " " << setprecision(6) << d << endl; + results << (stats.delay * _opt.time_mul) << " " << setprecision(6) << d + << endl; } cout << "Statistics written to: " << _stats_filename << endl; - } - catch (...) - { + } catch (...) { cout << "Failed to write statistics to: " << _stats_filename << endl; } } // make sure write files is intended -void -Responder::safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success, int return_code) +void Responder::safe_write_statistics_to_file( + StatsMap mapStats, uint64_t max_success, int return_code) { - if ((_opt.test_iterations > 0) && (_stats_filename.empty() == false) && (_opt.no_stats_file == false)) - { - if (mapStats.empty()) - { + if ((_opt.test_iterations > 0) && (_stats_filename.empty() == false) + && (_opt.no_stats_file == false)) { + if (mapStats.empty()) { cout << "No results to output (not writing statistics file)" << endl; - } - else if ((max_success == 0) && (return_code == RETCODE_MANUAL_ABORT)) - { - cout << "Aborted before a single successful timed burst (not writing statistics file)" << endl; - } - else - { + } else if ((max_success == 0) && (return_code == RETCODE_MANUAL_ABORT)) { + cout << "Aborted before a single successful timed burst (not writing " + "statistics file)" + << endl; + } else { write_statistics_to_file(mapStats); } write_log_file(); @@ -1400,10 +1373,10 @@ Responder::safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success Responder::~Responder() { endwin(); - if(_pResponse != NULL){ + if (_pResponse != NULL) { delete[] _pResponse; } - time( &_dbginfo.end_time ); + time(&_dbginfo.end_time); // Print final info about test run print_final_statistics(); // check conditions and write statistics to file @@ -1412,21 +1385,27 @@ Responder::~Responder() } // make test output more helpful -std::string -Responder::enum2str(int return_code) +std::string Responder::enum2str(int return_code) { - switch(return_code) - { - case RETCODE_OK: return "OK"; - case RETCODE_BAD_ARGS: return "BAD_ARGS"; - case RETCODE_RUNTIME_ERROR: return "RUNTIME_ERROR"; - case RETCODE_UNKNOWN_EXCEPTION: return "UNKNOWN_EXCEPTION"; - case RETCODE_RECEIVE_TIMEOUT: return "RECEIVE_TIMEOUT"; - case RETCODE_RECEIVE_FAILED: return "RECEIVE_FAILED"; - case RETCODE_MANUAL_ABORT: return "MANUAL_ABORT"; - case RETCODE_BAD_PACKET: return "BAD_PACKET"; - case RETCODE_OVERFLOW: return "OVERFLOW"; + switch (return_code) { + case RETCODE_OK: + return "OK"; + case RETCODE_BAD_ARGS: + return "BAD_ARGS"; + case RETCODE_RUNTIME_ERROR: + return "RUNTIME_ERROR"; + case RETCODE_UNKNOWN_EXCEPTION: + return "UNKNOWN_EXCEPTION"; + case RETCODE_RECEIVE_TIMEOUT: + return "RECEIVE_TIMEOUT"; + case RETCODE_RECEIVE_FAILED: + return "RECEIVE_FAILED"; + case RETCODE_MANUAL_ABORT: + return "MANUAL_ABORT"; + case RETCODE_BAD_PACKET: + return "BAD_PACKET"; + case RETCODE_OVERFLOW: + return "OVERFLOW"; } return "UNKNOWN"; } - diff --git a/host/utils/latency/responder.cpp b/host/utils/latency/responder.cpp index 6216f15e6..fd47ad085 100644 --- a/host/utils/latency/responder.cpp +++ b/host/utils/latency/responder.cpp @@ -5,16 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/program_options.hpp> #include <uhd/utils/safe_main.hpp> #include <Responder.hpp> +#include <boost/program_options.hpp> namespace po = boost::program_options; static Responder::Options prog; -po::options_description -get_program_options_description() +po::options_description get_program_options_description() { po::options_description desc("Allowed options"); // clang-format off @@ -71,41 +70,40 @@ get_program_options_description() return desc; } -void -read_program_options(po::variables_map vm) +void read_program_options(po::variables_map vm) { // read out given options prog.realtime = (vm.count("no-realtime") == 0); prog.delay_step = std::abs(prog.delay_step); - if (prog.delay_min > prog.delay_max) - { + if (prog.delay_min > prog.delay_max) { prog.delay_step *= -1; } - prog.allow_late_bursts = (vm.count("allow-late") > 0); + prog.allow_late_bursts = (vm.count("allow-late") > 0); prog.test_iterations_is_sample_count = (vm.count("test-duration") > 0); - prog.invert = ((vm.count("invert") > 0) ? -1.0f : 1.0f); - prog.output_value = ((vm.count("invert-output") > 0) ? -1.0f : 1.0f); - prog.skip_eob = (vm.count("skip-eob") > 0); - prog.no_delay = (vm.count("no-delay") > 0); - prog.adjust_simulation_rate = (vm.count("adjust-simulation-rate") > 0); + prog.invert = ((vm.count("invert") > 0) ? -1.0f : 1.0f); + prog.output_value = ((vm.count("invert-output") > 0) ? -1.0f : 1.0f); + prog.skip_eob = (vm.count("skip-eob") > 0); + prog.no_delay = (vm.count("no-delay") > 0); + prog.adjust_simulation_rate = (vm.count("adjust-simulation-rate") > 0); prog.optimize_simulation_rate = (vm.count("optimize-simulation-rate") > 0); - prog.no_stats_file = (vm.count("no-stats-file") > 0); - prog.log_file = (vm.count("log-file") > 0); - prog.batch_mode = (vm.count("batch-mode") > 0); - prog.skip_if_results_exist = (vm.count("skip-if-exists") > 0); - prog.skip_send = (vm.count("disable-send") > 0); - prog.combine_eob = (vm.count("combine-eob") > 0); - prog.pause = (vm.count("pause") > 0); - prog.ignore_simulation_check = vm.count("ignore-simulation-check"); + prog.no_stats_file = (vm.count("no-stats-file") > 0); + prog.log_file = (vm.count("log-file") > 0); + prog.batch_mode = (vm.count("batch-mode") > 0); + prog.skip_if_results_exist = (vm.count("skip-if-exists") > 0); + prog.skip_send = (vm.count("disable-send") > 0); + prog.combine_eob = (vm.count("combine-eob") > 0); + prog.pause = (vm.count("pause") > 0); + prog.ignore_simulation_check = vm.count("ignore-simulation-check"); } /* * This is the MAIN function! * UHD_SAFE_MAIN catches all errors and prints them to stderr. */ -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc = get_program_options_description(); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -113,13 +111,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ read_program_options(vm); // Print help message instead of executing Responder. - if (vm.count("help")){ + if (vm.count("help")) { cout << boost::format("UHD Latency Test %s") % desc; return Responder::RETCODE_OK; } - //create a new instance of Responder and run it! + // create a new instance of Responder and run it! boost::shared_ptr<Responder> my_responder(new Responder(prog)); return my_responder->run(); } - diff --git a/host/utils/octoclock_burn_eeprom.cpp b/host/utils/octoclock_burn_eeprom.cpp index f98f526f6..6221c4e83 100644 --- a/host/utils/octoclock_burn_eeprom.cpp +++ b/host/utils/octoclock_burn_eeprom.cpp @@ -6,13 +6,13 @@ // #include <uhd/device.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/usrp_clock/octoclock_eeprom.hpp> #include <uhd/property_tree.hpp> #include <uhd/types/device_addr.hpp> +#include <uhd/usrp_clock/octoclock_eeprom.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string.hpp> -#include <boost/program_options.hpp> #include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> #include <vector> @@ -21,7 +21,8 @@ namespace po = boost::program_options; using namespace uhd; using namespace uhd::usrp_clock; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ std::string args, input_str, key, val; po::options_description desc("Allowed options"); @@ -38,50 +39,60 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))){ + // print the help message + if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))) { std::cout << boost::format("OctoClock Burn EEPROM %s") % desc << std::endl; - std::cout << boost::format( - "Omit the value argument to perform a readback,\n" - "Or specify a new value to burn into the EEPROM.\n" - ) << std::endl; + std::cout << boost::format("Omit the value argument to perform a readback,\n" + "Or specify a new value to burn into the EEPROM.\n") + << std::endl; return EXIT_FAILURE; } std::cout << "Creating OctoClock device from args: " + args << std::endl; - device::sptr oc = device::make(args, device::CLOCK); + device::sptr oc = device::make(args, device::CLOCK); property_tree::sptr tree = oc->get_tree(); - octoclock_eeprom_t oc_eeprom = tree->access<octoclock_eeprom_t>("/mboards/0/eeprom").get(); + octoclock_eeprom_t oc_eeprom = + tree->access<octoclock_eeprom_t>("/mboards/0/eeprom").get(); std::cout << std::endl; std::vector<std::string> keys_vec, vals_vec; - if(vm.count("read-all")) keys_vec = oc_eeprom.keys(); //Leaving vals_vec empty will force utility to only read - else if(vm.count("values")){ - //uhd::device_addr_t properly parses input values + if (vm.count("read-all")) + keys_vec = + oc_eeprom.keys(); // Leaving vals_vec empty will force utility to only read + else if (vm.count("values")) { + // uhd::device_addr_t properly parses input values device_addr_t vals(input_str); keys_vec = vals.keys(); vals_vec = vals.vals(); - } - else throw std::runtime_error("Must specify --values or --read-all option!"); + } else + throw std::runtime_error("Must specify --values or --read-all option!"); std::cout << "Fetching current settings from EEPROM..." << std::endl; - for(size_t i = 0; i < keys_vec.size(); i++){ - if (not oc_eeprom.has_key(keys_vec[i])){ - std::cerr << boost::format("Cannot find value for EEPROM[\"%s\"]") % keys_vec[i] << std::endl; + for (size_t i = 0; i < keys_vec.size(); i++) { + if (not oc_eeprom.has_key(keys_vec[i])) { + std::cerr << boost::format("Cannot find value for EEPROM[\"%s\"]") + % keys_vec[i] + << std::endl; return EXIT_FAILURE; } - std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] % oc_eeprom[keys_vec[i]] << std::endl; + std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] + % oc_eeprom[keys_vec[i]] + << std::endl; } - if(!vm.count("read-all")){ + if (!vm.count("read-all")) { std::cout << std::endl; - for(size_t i = 0; i < vals_vec.size(); i++){ - if(vals_vec[i] != ""){ + for (size_t i = 0; i < vals_vec.size(); i++) { + if (vals_vec[i] != "") { oc_eeprom[keys_vec[i]] = vals_vec[i]; - std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") % keys_vec[i] % vals_vec[i] << std::endl; + std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") + % keys_vec[i] % vals_vec[i] + << std::endl; } } tree->access<octoclock_eeprom_t>("/mboards/0/eeprom").set(oc_eeprom); } - std::cout << std::endl << "Power-cycle your device to allow any changes to take effect." << std::endl; + std::cout << std::endl + << "Power-cycle your device to allow any changes to take effect." + << std::endl; return EXIT_SUCCESS; } diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp index 6a3ecca13..4a8aa24d2 100644 --- a/host/utils/query_gpsdo_sensors.cpp +++ b/host/utils/query_gpsdo_sensors.cpp @@ -5,241 +5,270 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/paths.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/usrp/multi_usrp.hpp> #include <uhd/usrp_clock/multi_usrp_clock.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/filesystem.hpp> -#include <boost/program_options.hpp> #include <boost/format.hpp> -#include <iostream> -#include <complex> -#include <string> +#include <boost/program_options.hpp> +#include <chrono> #include <cmath> -#include <ctime> +#include <complex> #include <cstdlib> -#include <chrono> +#include <ctime> +#include <iostream> +#include <string> #include <thread> namespace po = boost::program_options; namespace fs = boost::filesystem; -void print_notes(void) { - // Helpful notes - std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n"); - std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n"); - std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n"); - std::cout << boost::format("****************************************************************************************************************\n"); +void print_notes(void) +{ + // Helpful notes + std::cout << boost::format( + "**************************************Helpful Notes on Clock/PPS " + "Selection**************************************\n"); + std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS " + "signals are now from the GPSDO.\n"); + std::cout << boost::format( + "If you would like to use the internal reference(TCXO) in other applications, " + "you must configure that explicitly.\n"); + std::cout << boost::format( + "********************************************************************************" + "********************************\n"); } -int query_clock_sensors(const std::string &args) { - std::cout << boost::format("\nCreating the clock device with: %s...\n") % args; - uhd::usrp_clock::multi_usrp_clock::sptr clock = uhd::usrp_clock::multi_usrp_clock::make(args); - - //Verify GPS sensors are present - std::vector<std::string> sensor_names = clock->get_sensor_names(0); - if(std::find(sensor_names.begin(), sensor_names.end(), "gps_locked") == sensor_names.end()) { - std::cout << boost::format("\ngps_locked sensor not found. This could mean that this unit does not have a GPSDO.\n\n"); - return EXIT_FAILURE; - } - - // Print NMEA strings - try { - uhd::sensor_value_t gga_string = clock->get_sensor("gps_gpgga"); - uhd::sensor_value_t rmc_string = clock->get_sensor("gps_gprmc"); - uhd::sensor_value_t servo_string = clock->get_sensor("gps_servo"); - std::cout << boost::format("\nPrinting available NMEA strings:\n"); - std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() % rmc_string.to_pp_string(); - std::cout << boost::format("\nPrinting GPS servo status:\n"); - std::cout << boost::format("%s\n\n") % servo_string.to_pp_string(); - } catch (const uhd::lookup_error &) { - std::cout << "NMEA strings not implemented for this device." << std::endl; - } - std::cout << boost::format("GPS Epoch time: %.5f seconds\n") % clock->get_sensor("gps_time").to_real(); - std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); - - //finished - std::cout << boost::format("\nDone!\n\n"); - - return EXIT_SUCCESS; +int query_clock_sensors(const std::string& args) +{ + std::cout << boost::format("\nCreating the clock device with: %s...\n") % args; + uhd::usrp_clock::multi_usrp_clock::sptr clock = + uhd::usrp_clock::multi_usrp_clock::make(args); + + // Verify GPS sensors are present + std::vector<std::string> sensor_names = clock->get_sensor_names(0); + if (std::find(sensor_names.begin(), sensor_names.end(), "gps_locked") + == sensor_names.end()) { + std::cout << boost::format("\ngps_locked sensor not found. This could mean that " + "this unit does not have a GPSDO.\n\n"); + return EXIT_FAILURE; + } + + // Print NMEA strings + try { + uhd::sensor_value_t gga_string = clock->get_sensor("gps_gpgga"); + uhd::sensor_value_t rmc_string = clock->get_sensor("gps_gprmc"); + uhd::sensor_value_t servo_string = clock->get_sensor("gps_servo"); + std::cout << boost::format("\nPrinting available NMEA strings:\n"); + std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() + % rmc_string.to_pp_string(); + std::cout << boost::format("\nPrinting GPS servo status:\n"); + std::cout << boost::format("%s\n\n") % servo_string.to_pp_string(); + } catch (const uhd::lookup_error&) { + std::cout << "NMEA strings not implemented for this device." << std::endl; + } + std::cout << boost::format("GPS Epoch time: %.5f seconds\n") + % clock->get_sensor("gps_time").to_real(); + std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); + + // finished + std::cout << boost::format("\nDone!\n\n"); + + return EXIT_SUCCESS; } -int UHD_SAFE_MAIN(int argc, char *argv[]){ - uhd::set_thread_priority_safe(); +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ + uhd::set_thread_priority_safe(); - std::string args; + std::string args; - //Set up program options - po::options_description desc("Allowed options"); - // clang-format off + // Set up program options + po::options_description desc("Allowed options"); + // clang-format off desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "Device address arguments specifying a single USRP") ("clock", "query a clock device's sensors") ; - // clang-format on - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //Print the help message - if (vm.count("help")) { - std::cout << boost::format("Query GPSDO Sensors, try to lock the reference oscillator to the GPS disciplined clock, and set the device time to GPS time") - << std::endl - << std::endl - << desc; - return EXIT_FAILURE; - } - - //If specified, query a clock device instead - if(vm.count("clock")) { - return query_clock_sensors(args); - } - - //Create a USRP device - std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; - uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); - std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); - - //Verify GPS sensors are present (i.e. EEPROM has been burnt) - std::vector<std::string> sensor_names = usrp->get_mboard_sensor_names(0); - - if (std::find(sensor_names.begin(), sensor_names.end(), "gps_locked") == sensor_names.end()) { - std::cout << boost::format("\ngps_locked sensor not found. This could mean that you have not installed the GPSDO correctly.\n\n"); - std::cout << boost::format("Visit one of these pages if the problem persists:\n"); - std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html\n"); - std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); - return EXIT_FAILURE; - } - - bool ref_set_to_gpsdo = false; - - // Set clock source to gpsdo if supported - if (uhd::has(usrp->get_clock_sources(0),"gpsdo")) - { - std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; - usrp->set_clock_source("gpsdo"); - ref_set_to_gpsdo = true; - } - std::cout << "Clock source is now " << usrp->get_clock_source(0) << std::endl; - - // Set time source to gpsdo if supported - if (uhd::has(usrp->get_time_sources(0),"gpsdo")) - { - std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; - usrp->set_time_source("gpsdo"); - ref_set_to_gpsdo = true; - } - std::cout << "Time source is now " << usrp->get_time_source(0) << std::endl; - - if (not ref_set_to_gpsdo) - { - std::cerr << "ERROR: Unable to set clock or time reference to \"gpsdo\"" << std::endl; - return EXIT_FAILURE; - } - - //Check for ref lock - if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { - uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); - for (size_t i = 0; not ref_locked.to_bool() and i < 300; i++) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ref_locked = usrp->get_mboard_sensor("ref_locked",0); - } - if(not ref_locked.to_bool()) { - std::cout << boost::format("USRP NOT Locked to Reference.\n"); - std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); - return EXIT_FAILURE; - } else { - std::cout << boost::format("USRP Locked to Reference.\n"); - } - } else { - std::cout << boost::format("ref_locked sensor not present on this board.\n"); - } - - print_notes(); - - // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data - // to show up - std::cout << "Waiting for the GPSDO to warm up..." << std::flush; - auto end = std::chrono::steady_clock::now() + std::chrono::seconds(30); - while (std::chrono::steady_clock::now() < end) { - try { - usrp->get_mboard_sensor("gps_locked", 0); - break; - } catch (std::exception &) {} - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - std::cout << "." << std::flush; - } - std::cout << std::endl; - try { - usrp->get_mboard_sensor("gps_locked", 0); - } catch (std::exception &) { - std::cout << "No response from GPSDO in 30 seconds" << std::endl; - return EXIT_FAILURE; - } - std::cout << "The GPSDO is warmed up and talking." << std::endl; - - //Check for GPS lock - uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0);; - if(not gps_locked.to_bool()) { - std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n"); - std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n"); - } else { - std::cout << boost::format("GPS Locked"); - } - - //Check PPS and compare UHD device time to GPS time - uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time"); - uhd::time_spec_t last_pps_time = usrp->get_time_last_pps(); - - //we only care about the full seconds - signed gps_seconds = gps_time.to_int(); - long long pps_seconds = last_pps_time.to_ticks(1.0); - - if(pps_seconds != gps_seconds) { - std::cout << "\nTrying to align the device time to GPS time..." - << std::endl; - - gps_time = usrp->get_mboard_sensor("gps_time"); - - //set the device time to the GPS time - //getting the GPS time returns just after the PPS edge, so just add a - //second and set the device time at the next PPS edge - usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0)); - //allow some time to make sure the PPS has come… - std::this_thread::sleep_for(std::chrono::milliseconds(1100)); - //…then ask - gps_seconds = usrp->get_mboard_sensor("gps_time").to_int(); - pps_seconds = usrp->get_time_last_pps().to_ticks(1.0); - } - - if (pps_seconds == gps_seconds) { - std::cout << boost::format("GPS and UHD Device time are aligned.\n"); - } else { - std::cout << boost::format("Could not align UHD Device time to GPS time. Giving up.\n"); - } - std::cout << boost::format("last_pps: %ld vs gps: %ld.") - % pps_seconds % gps_seconds - << std::endl; - - //print NMEA strings - try { - uhd::sensor_value_t gga_string = usrp->get_mboard_sensor("gps_gpgga"); - uhd::sensor_value_t rmc_string = usrp->get_mboard_sensor("gps_gprmc"); - std::cout << boost::format("Printing available NMEA strings:\n"); - std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() % rmc_string.to_pp_string(); - } catch (uhd::lookup_error&) { - std::cout << "NMEA strings not implemented for this device." << std::endl; - } - std::cout << boost::format("GPS Epoch time at last PPS: %.5f seconds\n") % usrp->get_mboard_sensor("gps_time").to_real(); - std::cout << boost::format("UHD Device time last PPS: %.5f seconds\n") % (usrp->get_time_last_pps().get_real_secs()); - std::cout << boost::format("UHD Device time right now: %.5f seconds\n") % (usrp->get_time_now().get_real_secs()); - std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); - - //finished - std::cout << boost::format("\nDone!\n\n"); - - return EXIT_SUCCESS; + // clang-format on + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + // Print the help message + if (vm.count("help")) { + std::cout << boost::format( + "Query GPSDO Sensors, try to lock the reference oscillator to " + "the GPS disciplined clock, and set the device time to GPS time") + << std::endl + << std::endl + << desc; + return EXIT_FAILURE; + } + + // If specified, query a clock device instead + if (vm.count("clock")) { + return query_clock_sensors(args); + } + + // Create a USRP device + std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; + uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); + std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); + + // Verify GPS sensors are present (i.e. EEPROM has been burnt) + std::vector<std::string> sensor_names = usrp->get_mboard_sensor_names(0); + + if (std::find(sensor_names.begin(), sensor_names.end(), "gps_locked") + == sensor_names.end()) { + std::cout << boost::format("\ngps_locked sensor not found. This could mean that " + "you have not installed the GPSDO correctly.\n\n"); + std::cout << boost::format("Visit one of these pages if the problem persists:\n"); + std::cout << boost::format( + " * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html\n"); + std::cout << boost::format( + " * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); + return EXIT_FAILURE; + } + + bool ref_set_to_gpsdo = false; + + // Set clock source to gpsdo if supported + if (uhd::has(usrp->get_clock_sources(0), "gpsdo")) { + std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; + usrp->set_clock_source("gpsdo"); + ref_set_to_gpsdo = true; + } + std::cout << "Clock source is now " << usrp->get_clock_source(0) << std::endl; + + // Set time source to gpsdo if supported + if (uhd::has(usrp->get_time_sources(0), "gpsdo")) { + std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; + usrp->set_time_source("gpsdo"); + ref_set_to_gpsdo = true; + } + std::cout << "Time source is now " << usrp->get_time_source(0) << std::endl; + + if (not ref_set_to_gpsdo) { + std::cerr << "ERROR: Unable to set clock or time reference to \"gpsdo\"" + << std::endl; + return EXIT_FAILURE; + } + + // Check for ref lock + if (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") + != sensor_names.end()) { + uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked", 0); + for (size_t i = 0; not ref_locked.to_bool() and i < 300; i++) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + ref_locked = usrp->get_mboard_sensor("ref_locked", 0); + } + if (not ref_locked.to_bool()) { + std::cout << boost::format("USRP NOT Locked to Reference.\n"); + std::cout << boost::format( + "Double check installation instructions (N2X0/E1X0 only): " + "https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); + return EXIT_FAILURE; + } else { + std::cout << boost::format("USRP Locked to Reference.\n"); + } + } else { + std::cout << boost::format("ref_locked sensor not present on this board.\n"); + } + + print_notes(); + + // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data + // to show up + std::cout << "Waiting for the GPSDO to warm up..." << std::flush; + auto end = std::chrono::steady_clock::now() + std::chrono::seconds(30); + while (std::chrono::steady_clock::now() < end) { + try { + usrp->get_mboard_sensor("gps_locked", 0); + break; + } catch (std::exception&) { + } + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + std::cout << "." << std::flush; + } + std::cout << std::endl; + try { + usrp->get_mboard_sensor("gps_locked", 0); + } catch (std::exception&) { + std::cout << "No response from GPSDO in 30 seconds" << std::endl; + return EXIT_FAILURE; + } + std::cout << "The GPSDO is warmed up and talking." << std::endl; + + // Check for GPS lock + uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked", 0); + ; + if (not gps_locked.to_bool()) { + std::cout << boost::format( + "\nGPS does not have lock. Wait a few minutes and try again.\n"); + std::cout << boost::format("NMEA strings and device time may not be accurate " + "until lock is achieved.\n\n"); + } else { + std::cout << boost::format("GPS Locked"); + } + + // Check PPS and compare UHD device time to GPS time + uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time"); + uhd::time_spec_t last_pps_time = usrp->get_time_last_pps(); + + // we only care about the full seconds + signed gps_seconds = gps_time.to_int(); + long long pps_seconds = last_pps_time.to_ticks(1.0); + + if (pps_seconds != gps_seconds) { + std::cout << "\nTrying to align the device time to GPS time..." << std::endl; + + gps_time = usrp->get_mboard_sensor("gps_time"); + + // set the device time to the GPS time + // getting the GPS time returns just after the PPS edge, so just add a + // second and set the device time at the next PPS edge + usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0)); + // allow some time to make sure the PPS has come… + std::this_thread::sleep_for(std::chrono::milliseconds(1100)); + //…then ask + gps_seconds = usrp->get_mboard_sensor("gps_time").to_int(); + pps_seconds = usrp->get_time_last_pps().to_ticks(1.0); + } + + if (pps_seconds == gps_seconds) { + std::cout << boost::format("GPS and UHD Device time are aligned.\n"); + } else { + std::cout << boost::format( + "Could not align UHD Device time to GPS time. Giving up.\n"); + } + std::cout << boost::format("last_pps: %ld vs gps: %ld.") % pps_seconds % gps_seconds + << std::endl; + + // print NMEA strings + try { + uhd::sensor_value_t gga_string = usrp->get_mboard_sensor("gps_gpgga"); + uhd::sensor_value_t rmc_string = usrp->get_mboard_sensor("gps_gprmc"); + std::cout << boost::format("Printing available NMEA strings:\n"); + std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() + % rmc_string.to_pp_string(); + } catch (uhd::lookup_error&) { + std::cout << "NMEA strings not implemented for this device." << std::endl; + } + std::cout << boost::format("GPS Epoch time at last PPS: %.5f seconds\n") + % usrp->get_mboard_sensor("gps_time").to_real(); + std::cout << boost::format("UHD Device time last PPS: %.5f seconds\n") + % (usrp->get_time_last_pps().get_real_secs()); + std::cout << boost::format("UHD Device time right now: %.5f seconds\n") + % (usrp->get_time_now().get_real_secs()); + std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); + + // finished + std::cout << boost::format("\nDone!\n\n"); + + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp index d8c6a63da..a90e37651 100644 --- a/host/utils/uhd_cal_rx_iq_balance.cpp +++ b/host/utils/uhd_cal_rx_iq_balance.cpp @@ -6,21 +6,21 @@ // #include "usrp_cal_utils.hpp" -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <boost/thread/thread.hpp> #include <boost/math/special_functions/round.hpp> -#include <iostream> -#include <complex> +#include <boost/program_options.hpp> +#include <boost/thread/thread.hpp> +#include <chrono> #include <cmath> -#include <ctime> +#include <complex> #include <cstdlib> -#include <chrono> +#include <ctime> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -32,20 +32,19 @@ static void tx_thread(uhd::tx_streamer::sptr tx_stream, const double tx_wave_amp { uhd::set_thread_priority_safe(); - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; - std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); + std::vector<samp_type> buff(tx_stream->get_max_num_samps() * 10); - //fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) - { + // fill buff and send until interrupted + while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = float(tx_wave_ampl); tx_stream->send(&buff.front(), buff.size(), md); } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } @@ -53,21 +52,22 @@ static void tx_thread(uhd::tx_streamer::sptr tx_stream, const double tx_wave_amp /*********************************************************************** * Tune RX and TX routine **********************************************************************/ -static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double rx_lo_freq, const double tx_offset) +static double tune_rx_and_tx( + uhd::usrp::multi_usrp::sptr usrp, const double rx_lo_freq, const double tx_offset) { - //tune the receiver with no cordic + // tune the receiver with no cordic uhd::tune_request_t rx_tune_req(rx_lo_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.dsp_freq = 0; + rx_tune_req.dsp_freq = 0; usrp->set_rx_freq(rx_tune_req); - //tune the transmitter - double tx_freq = usrp->get_rx_freq() + tx_offset; + // tune the transmitter + double tx_freq = usrp->get_rx_freq() + tx_offset; double min_fe_tx_freq = usrp->get_fe_tx_freq_range().start(); double max_fe_tx_freq = usrp->get_fe_tx_freq_range().stop(); uhd::tune_request_t tx_tune_req(tx_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - tx_tune_req.dsp_freq = 0; + tx_tune_req.dsp_freq = 0; if (tx_freq < min_fe_tx_freq) tx_tune_req.dsp_freq = tx_freq - min_fe_tx_freq; else if (tx_freq > max_fe_tx_freq) @@ -82,7 +82,7 @@ static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double rx_l /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string args, subdev, serial; double tx_wave_ampl, tx_offset; @@ -111,13 +111,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ - std::cout << boost::format("USRP Generate RX IQ Balance Calibration Table %s") % desc << std::endl; - std::cout << - "This application measures leakage between RX and TX on a transceiver daughterboard to self-calibrate.\n" - "Note: Not all daughterboards support this feature. Refer to the UHD manual for details.\n" - << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Generate RX IQ Balance Calibration Table %s") + % desc + << std::endl; + std::cout << "This application measures leakage between RX and TX on a " + "transceiver daughterboard to self-calibrate.\n" + "Note: Not all daughterboards support this feature. Refer to the " + "UHD manual for details.\n" + << std::endl; return EXIT_FAILURE; } @@ -127,143 +130,154 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (not vm.count("nsamps")) nsamps = size_t(usrp->get_rx_rate() / default_fft_bin_size); - //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + // create a receive streamer + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //create a transmit streamer + // create a transmit streamer uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //create a transmitter thread + // create a transmitter thread boost::thread_group threads; threads.create_thread(boost::bind(&tx_thread, tx_stream, tx_wave_ampl)); - //re-usable buffer for samples + // re-usable buffer for samples std::vector<samp_type> buff; - //store the results here + // store the results here std::vector<result_t> results; - if (not vm.count("freq_start")) freq_start = usrp->get_fe_rx_freq_range().start(); - if (not vm.count("freq_stop")) freq_stop = usrp->get_fe_tx_freq_range().stop(); + if (not vm.count("freq_start")) + freq_start = usrp->get_fe_rx_freq_range().start(); + if (not vm.count("freq_stop")) + freq_stop = usrp->get_fe_tx_freq_range().stop(); - //check start and stop frequencies - if (freq_start < usrp->get_fe_rx_freq_range().start()) - { - std::cerr << "freq_start must be " << usrp->get_fe_rx_freq_range().start() << " or greater for this daughter board" << std::endl; + // check start and stop frequencies + if (freq_start < usrp->get_fe_rx_freq_range().start()) { + std::cerr << "freq_start must be " << usrp->get_fe_rx_freq_range().start() + << " or greater for this daughter board" << std::endl; return EXIT_FAILURE; } - if (freq_stop > usrp->get_fe_rx_freq_range().stop()) - { - std::cerr << "freq_stop must be " << usrp->get_fe_rx_freq_range().stop() << " or less for this daughter board" << std::endl; + if (freq_stop > usrp->get_fe_rx_freq_range().stop()) { + std::cerr << "freq_stop must be " << usrp->get_fe_rx_freq_range().stop() + << " or less for this daughter board" << std::endl; return EXIT_FAILURE; } - //check tx_offset - double min_tx_offset = usrp->get_tx_freq_range().start() - usrp->get_fe_rx_freq_range().start(); - double max_tx_offset = usrp->get_tx_freq_range().stop() - usrp->get_fe_rx_freq_range().stop(); - if (tx_offset < min_tx_offset or tx_offset > max_tx_offset) - { + // check tx_offset + double min_tx_offset = + usrp->get_tx_freq_range().start() - usrp->get_fe_rx_freq_range().start(); + double max_tx_offset = + usrp->get_tx_freq_range().stop() - usrp->get_fe_rx_freq_range().stop(); + if (tx_offset < min_tx_offset or tx_offset > max_tx_offset) { std::cerr << "tx_offset must be between " << min_tx_offset << " and " - << max_tx_offset << " for this daughter board" << std::endl; + << max_tx_offset << " for this daughter board" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl; + std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") + % (freq_start / 1e6) % (freq_stop / 1e6) + << std::endl; size_t tx_error_count = 0; - for (double rx_lo_i = freq_start; rx_lo_i <= freq_stop; rx_lo_i += freq_step) - { + for (double rx_lo_i = freq_start; rx_lo_i <= freq_stop; rx_lo_i += freq_step) { const double rx_lo = tune_rx_and_tx(usrp, rx_lo_i, tx_offset); - //frequency constants for this tune event + // frequency constants for this tune event const double actual_rx_rate = usrp->get_rx_rate(); const double actual_tx_freq = usrp->get_tx_freq(); const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_tone_freq = actual_tx_freq - actual_rx_freq; - const double bb_imag_freq = -bb_tone_freq; + const double bb_tone_freq = actual_tx_freq - actual_rx_freq; + const double bb_imag_freq = -bb_tone_freq; - //reset RX IQ balance + // reset RX IQ balance usrp->set_rx_iq_balance(0.0); - //set optimal RX gain setting for this frequency + // set optimal RX gain setting for this frequency set_optimal_rx_gain(usrp, rx_stream); - //capture initial uncorrected value + // capture initial uncorrected value capture_samples(usrp, rx_stream, buff, nsamps); - const double initial_suppression = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate) - compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double initial_suppression = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate) + - compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); - //bounds and results from searching + // bounds and results from searching double phase_corr_start = -1.0; - double phase_corr_stop = 1.0; - double phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + double phase_corr_stop = 1.0; + double phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); double ampl_corr_start = -1.0; - double ampl_corr_stop = 1.0; - double ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + double ampl_corr_stop = 1.0; + double ampl_corr_step = + (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); double best_suppression = 0; - double best_phase_corr = 0; - double best_ampl_corr = 0; - while (phase_corr_step >= precision or ampl_corr_step >= precision) - { - for (double phase_corr = phase_corr_start + phase_corr_step; phase_corr <= phase_corr_stop - phase_corr_step; phase_corr += phase_corr_step) - { - for (double ampl_corr = ampl_corr_start + ampl_corr_step; ampl_corr <= ampl_corr_stop - ampl_corr_step; ampl_corr += ampl_corr_step) - { + double best_phase_corr = 0; + double best_ampl_corr = 0; + while (phase_corr_step >= precision or ampl_corr_step >= precision) { + for (double phase_corr = phase_corr_start + phase_corr_step; + phase_corr <= phase_corr_stop - phase_corr_step; + phase_corr += phase_corr_step) { + for (double ampl_corr = ampl_corr_start + ampl_corr_step; + ampl_corr <= ampl_corr_stop - ampl_corr_step; + ampl_corr += ampl_corr_step) { const std::complex<double> correction(ampl_corr, phase_corr); usrp->set_rx_iq_balance(correction); - //receive some samples + // receive some samples capture_samples(usrp, rx_stream, buff, nsamps); - //check for TX errors in the current captured iteration - if (has_tx_error(tx_stream)){ + // check for TX errors in the current captured iteration + if (has_tx_error(tx_stream)) { if (vm.count("verbose")) { - std::cout - << "[WARNING] TX error detected! " - << "Repeating current iteration" - << std::endl; + std::cout << "[WARNING] TX error detected! " + << "Repeating current iteration" << std::endl; } // Undo the correction step: ampl_corr -= ampl_corr_step; tx_error_count++; if (tx_error_count >= MAX_NUM_TX_ERRORS) { throw uhd::runtime_error( - "Too many TX errors. Aborting calibration." - ); + "Too many TX errors. Aborting calibration."); } continue; } - const double tone_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); - const double imag_dbrms = compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double tone_dbrms = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); + const double imag_dbrms = + compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); const double suppression = tone_dbrms - imag_dbrms; - if (suppression > best_suppression) - { + if (suppression > best_suppression) { best_suppression = suppression; - best_phase_corr = phase_corr; - best_ampl_corr = ampl_corr; + best_phase_corr = phase_corr; + best_ampl_corr = ampl_corr; } } } phase_corr_start = best_phase_corr - phase_corr_step; - phase_corr_stop = best_phase_corr + phase_corr_step; - phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + phase_corr_stop = best_phase_corr + phase_corr_step; + phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); ampl_corr_start = best_ampl_corr - ampl_corr_step; - ampl_corr_stop = best_ampl_corr + ampl_corr_step; - ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + ampl_corr_stop = best_ampl_corr + ampl_corr_step; + ampl_corr_step = (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); } - if (best_suppression > initial_suppression) //keep result + if (best_suppression > initial_suppression) // keep result { result_t result; - result.freq = rx_lo; + result.freq = rx_lo; result.real_corr = best_ampl_corr; result.imag_corr = best_phase_corr; - result.best = best_suppression; - result.delta = best_suppression - initial_suppression; + result.best = best_suppression; + result.delta = best_suppression - initial_suppression; results.push_back(result); if (vm.count("verbose")) - std::cout << boost::format("RX IQ: %f MHz: best suppression %f dB, corrected %f dB") % (rx_lo/1e6) % result.best % result.delta << std::endl; + std::cout << boost::format( + "RX IQ: %f MHz: best suppression %f dB, corrected %f dB") + % (rx_lo / 1e6) % result.best % result.delta + << std::endl; else std::cout << "." << std::flush; } @@ -273,9 +287,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } // end for each frequency loop std::cout << std::endl; - //stop the transmitter + // stop the transmitter threads.interrupt_all(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); //wait for threads to finish + std::this_thread::sleep_for( + std::chrono::milliseconds(500)); // wait for threads to finish threads.join_all(); store_results(results, "RX", "rx", "iq", serial); diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp index 6519cd9ec..f47b5e913 100644 --- a/host/utils/uhd_cal_tx_dc_offset.cpp +++ b/host/utils/uhd_cal_tx_dc_offset.cpp @@ -6,19 +6,19 @@ // #include "usrp_cal_utils.hpp" -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <boost/thread/thread.hpp> #include <boost/math/special_functions/round.hpp> -#include <iostream> +#include <boost/program_options.hpp> +#include <boost/thread/thread.hpp> +#include <chrono> #include <complex> #include <ctime> -#include <chrono> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -26,33 +26,35 @@ namespace po = boost::program_options; /*********************************************************************** * Transmit thread **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, const double tx_wave_freq, const double tx_wave_ampl) +static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, + uhd::tx_streamer::sptr tx_stream, + const double tx_wave_freq, + const double tx_wave_ampl) { uhd::set_thread_priority_safe(); // set max TX gain usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; - std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); + std::vector<samp_type> buff(tx_stream->get_max_num_samps() * 10); - //values for the wave table lookup - size_t index = 0; + // values for the wave table lookup + size_t index = 0; const double tx_rate = usrp->get_tx_rate(); - const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); + const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); wave_table table(tx_wave_ampl); - //fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) - { + // fill buff and send until interrupted + while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = table(index += step); tx_stream->send(&buff.front(), buff.size(), md); } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } @@ -60,21 +62,22 @@ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr t /*********************************************************************** * Tune RX and TX routine **********************************************************************/ -static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) +static double tune_rx_and_tx( + uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) { - //tune the transmitter with no cordic + // tune the transmitter with no cordic uhd::tune_request_t tx_tune_req(tx_lo_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - tx_tune_req.dsp_freq = 0; + tx_tune_req.dsp_freq = 0; usrp->set_tx_freq(tx_tune_req); - //tune the receiver - double rx_freq = usrp->get_tx_freq() - rx_offset; + // tune the receiver + double rx_freq = usrp->get_tx_freq() - rx_offset; double min_fe_rx_freq = usrp->get_fe_rx_freq_range().start(); double max_fe_rx_freq = usrp->get_fe_rx_freq_range().stop(); uhd::tune_request_t rx_tune_req(rx_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.dsp_freq = 0; + rx_tune_req.dsp_freq = 0; if (rx_freq < min_fe_rx_freq) rx_tune_req.dsp_freq = rx_freq - min_fe_rx_freq; else if (rx_freq > max_fe_rx_freq) @@ -89,7 +92,7 @@ static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_l /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string args, subdev, serial; double tx_wave_freq, tx_wave_ampl, rx_offset; @@ -119,13 +122,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ - std::cout << boost::format("USRP Generate TX DC Offset Calibration Table %s") % desc << std::endl; - std::cout << - "This application measures leakage between RX and TX on a transceiver daughterboard to self-calibrate.\n" - "Note: Not all daughterboards support this feature. Refer to the UHD manual for details.\n" - << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Generate TX DC Offset Calibration Table %s") + % desc + << std::endl; + std::cout << "This application measures leakage between RX and TX on a " + "transceiver daughterboard to self-calibrate.\n" + "Note: Not all daughterboards support this feature. Refer to the " + "UHD manual for details.\n" + << std::endl; return EXIT_FAILURE; } @@ -135,138 +141,145 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (not vm.count("nsamps")) nsamps = size_t(usrp->get_rx_rate() / default_fft_bin_size); - //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + // create a receive streamer + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //create a transmit streamer + // create a transmit streamer uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //create a transmitter thread + // create a transmitter thread boost::thread_group threads; - threads.create_thread(boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); + threads.create_thread( + boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); - //re-usable buffer for samples + // re-usable buffer for samples std::vector<samp_type> buff; - //store the results here + // store the results here std::vector<result_t> results; - if (not vm.count("freq_start")) freq_start = usrp->get_fe_tx_freq_range().start(); - if (not vm.count("freq_stop")) freq_stop = usrp->get_fe_tx_freq_range().stop(); + if (not vm.count("freq_start")) + freq_start = usrp->get_fe_tx_freq_range().start(); + if (not vm.count("freq_stop")) + freq_stop = usrp->get_fe_tx_freq_range().stop(); - //check start and stop frequencies - if (freq_start < usrp->get_fe_tx_freq_range().start()) - { - std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() << " or greater for this daughter board" << std::endl; + // check start and stop frequencies + if (freq_start < usrp->get_fe_tx_freq_range().start()) { + std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() + << " or greater for this daughter board" << std::endl; return EXIT_FAILURE; } - if (freq_stop > usrp->get_fe_tx_freq_range().stop()) - { - std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() << " or less for this daughter board" << std::endl; + if (freq_stop > usrp->get_fe_tx_freq_range().stop()) { + std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() + << " or less for this daughter board" << std::endl; return EXIT_FAILURE; } - //check rx_offset - double min_rx_offset = usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); - double max_rx_offset = usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); - if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) - { + // check rx_offset + double min_rx_offset = + usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); + double max_rx_offset = + usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); + if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) { std::cerr << "rx_offset must be between " << min_rx_offset << " and " - << max_rx_offset << " for this daughter board" << std::endl; + << max_rx_offset << " for this daughter board" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl; + std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") + % (freq_start / 1e6) % (freq_stop / 1e6) + << std::endl; - //set RX gain + // set RX gain usrp->set_rx_gain(0); size_t tx_error_count = 0; - for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) - { + for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) { const double tx_lo = tune_rx_and_tx(usrp, tx_lo_i, rx_offset); - //frequency constants for this tune event + // frequency constants for this tune event const double actual_rx_rate = usrp->get_rx_rate(); const double actual_tx_freq = usrp->get_tx_freq(); const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_dc_freq = actual_tx_freq - actual_rx_freq; + const double bb_dc_freq = actual_tx_freq - actual_rx_freq; - //reset TX DC offset + // reset TX DC offset usrp->set_tx_dc_offset(std::complex<double>(0, 0)); - //capture initial uncorrected value + // capture initial uncorrected value capture_samples(usrp, rx_stream, buff, nsamps); - const double initial_dc_dbrms = compute_tone_dbrms(buff, bb_dc_freq/actual_rx_rate); - - //bounds and results from searching - double i_corr_start = -1.0; - double i_corr_stop = 1.0; - double i_corr_step = (i_corr_stop - i_corr_start)/(num_search_steps+1); - double q_corr_start = -1.0; - double q_corr_stop = 1.0; - double q_corr_step= (q_corr_stop - q_corr_start)/(num_search_steps+1); + const double initial_dc_dbrms = + compute_tone_dbrms(buff, bb_dc_freq / actual_rx_rate); + + // bounds and results from searching + double i_corr_start = -1.0; + double i_corr_stop = 1.0; + double i_corr_step = (i_corr_stop - i_corr_start) / (num_search_steps + 1); + double q_corr_start = -1.0; + double q_corr_stop = 1.0; + double q_corr_step = (q_corr_stop - q_corr_start) / (num_search_steps + 1); double best_dc_dbrms = initial_dc_dbrms; - double best_i_corr = 0; - double best_q_corr = 0; - while (i_corr_step >= precision or q_corr_step >= precision) - { - for (double i_corr = i_corr_start + i_corr_step; i_corr <= i_corr_stop - i_corr_step; i_corr += i_corr_step) - { - for (double q_corr = q_corr_start + q_corr_step; q_corr <= q_corr_stop - q_corr_step; q_corr += q_corr_step) - { + double best_i_corr = 0; + double best_q_corr = 0; + while (i_corr_step >= precision or q_corr_step >= precision) { + for (double i_corr = i_corr_start + i_corr_step; + i_corr <= i_corr_stop - i_corr_step; + i_corr += i_corr_step) { + for (double q_corr = q_corr_start + q_corr_step; + q_corr <= q_corr_stop - q_corr_step; + q_corr += q_corr_step) { const std::complex<double> correction(i_corr, q_corr); usrp->set_tx_dc_offset(correction); - //receive some samples + // receive some samples capture_samples(usrp, rx_stream, buff, nsamps); - //check for TX errors in the current captured iteration - if (has_tx_error(tx_stream)){ - std::cout - << "[WARNING] TX error detected! " - << "Repeating current iteration" - << std::endl; + // check for TX errors in the current captured iteration + if (has_tx_error(tx_stream)) { + std::cout << "[WARNING] TX error detected! " + << "Repeating current iteration" << std::endl; // Undo the Q correction step q_corr -= q_corr_step; tx_error_count++; if (tx_error_count >= MAX_NUM_TX_ERRORS) { throw uhd::runtime_error( - "Too many TX errors. Aborting calibration." - ); + "Too many TX errors. Aborting calibration."); } continue; } - const double dc_dbrms = compute_tone_dbrms(buff, bb_dc_freq/actual_rx_rate); + const double dc_dbrms = + compute_tone_dbrms(buff, bb_dc_freq / actual_rx_rate); - if (dc_dbrms < best_dc_dbrms) - { + if (dc_dbrms < best_dc_dbrms) { best_dc_dbrms = dc_dbrms; - best_i_corr = i_corr; - best_q_corr = q_corr; + best_i_corr = i_corr; + best_q_corr = q_corr; } } } i_corr_start = best_i_corr - i_corr_step; - i_corr_stop = best_i_corr + i_corr_step; - i_corr_step = (i_corr_stop - i_corr_start)/(num_search_steps+1); + i_corr_stop = best_i_corr + i_corr_step; + i_corr_step = (i_corr_stop - i_corr_start) / (num_search_steps + 1); q_corr_start = best_q_corr - q_corr_step; - q_corr_stop = best_q_corr + q_corr_step; - q_corr_step = (q_corr_stop - q_corr_start)/(num_search_steps+1); + q_corr_stop = best_q_corr + q_corr_step; + q_corr_step = (q_corr_stop - q_corr_start) / (num_search_steps + 1); } - if (best_dc_dbrms < initial_dc_dbrms) //keep result + if (best_dc_dbrms < initial_dc_dbrms) // keep result { result_t result; - result.freq = tx_lo; + result.freq = tx_lo; result.real_corr = best_i_corr; result.imag_corr = best_q_corr; - result.best = best_dc_dbrms; - result.delta = initial_dc_dbrms - best_dc_dbrms; + result.best = best_dc_dbrms; + result.delta = initial_dc_dbrms - best_dc_dbrms; results.push_back(result); if (vm.count("verbose")) - std::cout << boost::format("TX DC: %f MHz: lowest offset %f dB, corrected %f dB") % (tx_lo/1e6) % result.best % result.delta << std::endl; + std::cout << boost::format( + "TX DC: %f MHz: lowest offset %f dB, corrected %f dB") + % (tx_lo / 1e6) % result.best % result.delta + << std::endl; else std::cout << "." << std::flush; } @@ -277,9 +290,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::cout << std::endl; - //stop the transmitter + // stop the transmitter threads.interrupt_all(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); //wait for threads to finish + std::this_thread::sleep_for( + std::chrono::milliseconds(500)); // wait for threads to finish threads.join_all(); store_results(results, "TX", "tx", "dc", serial); diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp index 4da5a1f96..2e7229fd3 100644 --- a/host/utils/uhd_cal_tx_iq_balance.cpp +++ b/host/utils/uhd_cal_tx_iq_balance.cpp @@ -6,16 +6,16 @@ // #include "usrp_cal_utils.hpp" -#include <uhd/utils/thread.hpp> #include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/math/special_functions/round.hpp> #include <boost/program_options.hpp> #include <boost/thread/thread.hpp> -#include <boost/math/special_functions/round.hpp> -#include <iostream> +#include <chrono> #include <complex> -#include <ctime> #include <cstdlib> -#include <chrono> +#include <ctime> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -23,33 +23,35 @@ namespace po = boost::program_options; /*********************************************************************** * Transmit thread **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, const double tx_wave_freq, const double tx_wave_ampl) +static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, + uhd::tx_streamer::sptr tx_stream, + const double tx_wave_freq, + const double tx_wave_ampl) { uhd::set_thread_priority_safe(); // set max TX gain usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; - std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); + std::vector<samp_type> buff(tx_stream->get_max_num_samps() * 10); - //values for the wave table lookup - size_t index = 0; + // values for the wave table lookup + size_t index = 0; const double tx_rate = usrp->get_tx_rate(); - const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); + const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); wave_table table(tx_wave_ampl); - //fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) - { + // fill buff and send until interrupted + while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = table(index += step); tx_stream->send(&buff.front(), buff.size(), md); } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } @@ -57,21 +59,22 @@ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr t /*********************************************************************** * Tune RX and TX routine **********************************************************************/ -static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) +static double tune_rx_and_tx( + uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) { - //tune the transmitter with no cordic + // tune the transmitter with no cordic uhd::tune_request_t tx_tune_req(tx_lo_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - tx_tune_req.dsp_freq = 0; + tx_tune_req.dsp_freq = 0; usrp->set_tx_freq(tx_tune_req); - //tune the receiver - double rx_freq = usrp->get_tx_freq() - rx_offset; + // tune the receiver + double rx_freq = usrp->get_tx_freq() - rx_offset; double min_fe_rx_freq = usrp->get_fe_rx_freq_range().start(); double max_fe_rx_freq = usrp->get_fe_rx_freq_range().stop(); uhd::tune_request_t rx_tune_req(rx_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.dsp_freq = 0; + rx_tune_req.dsp_freq = 0; if (rx_freq < min_fe_rx_freq) rx_tune_req.dsp_freq = rx_freq - min_fe_rx_freq; else if (rx_freq > max_fe_rx_freq) @@ -86,7 +89,7 @@ static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_l /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string args, subdev, serial; double tx_wave_freq, tx_wave_ampl, rx_offset; @@ -116,14 +119,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")) - { - std::cout << boost::format("USRP Generate TX IQ Balance Calibration Table %s") % desc << std::endl; - std::cout << - "This application measures leakage between RX and TX on a transceiver daughterboard to self-calibrate.\n" - "Note: Not all daughterboards support this feature. Refer to the UHD manual for details.\n" - << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Generate TX IQ Balance Calibration Table %s") + % desc + << std::endl; + std::cout << "This application measures leakage between RX and TX on a " + "transceiver daughterboard to self-calibrate.\n" + "Note: Not all daughterboards support this feature. Refer to the " + "UHD manual for details.\n" + << std::endl; return EXIT_FAILURE; } @@ -133,140 +138,151 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (not vm.count("nsamps")) nsamps = size_t(usrp->get_rx_rate() / default_fft_bin_size); - //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + // create a receive streamer + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //create a transmit streamer + // create a transmit streamer uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //create a transmitter thread + // create a transmitter thread boost::thread_group threads; - threads.create_thread(boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); + threads.create_thread( + boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); - //re-usable buffer for samples + // re-usable buffer for samples std::vector<samp_type> buff; - //store the results here + // store the results here std::vector<result_t> results; - if (not vm.count("freq_start")) freq_start = usrp->get_fe_tx_freq_range().start(); - if (not vm.count("freq_stop")) freq_stop = usrp->get_fe_tx_freq_range().stop(); + if (not vm.count("freq_start")) + freq_start = usrp->get_fe_tx_freq_range().start(); + if (not vm.count("freq_stop")) + freq_stop = usrp->get_fe_tx_freq_range().stop(); - //check start and stop frequencies - if (freq_start < usrp->get_fe_tx_freq_range().start()) - { - std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() << " or greater for this daughter board" << std::endl; + // check start and stop frequencies + if (freq_start < usrp->get_fe_tx_freq_range().start()) { + std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() + << " or greater for this daughter board" << std::endl; return EXIT_FAILURE; } - if (freq_stop > usrp->get_fe_tx_freq_range().stop()) - { - std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() << " or less for this daughter board" << std::endl; + if (freq_stop > usrp->get_fe_tx_freq_range().stop()) { + std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() + << " or less for this daughter board" << std::endl; return EXIT_FAILURE; } - //check rx_offset - double min_rx_offset = usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); - double max_rx_offset = usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); - if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) - { + // check rx_offset + double min_rx_offset = + usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); + double max_rx_offset = + usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); + if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) { std::cerr << "rx_offset must be between " << min_rx_offset << " and " - << max_rx_offset << " for this daughter board" << std::endl; + << max_rx_offset << " for this daughter board" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl; + std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") + % (freq_start / 1e6) % (freq_stop / 1e6) + << std::endl; size_t tx_error_count = 0; - for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) - { - + for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) { const double tx_lo = tune_rx_and_tx(usrp, tx_lo_i, rx_offset); - //frequency constants for this tune event + // frequency constants for this tune event const double actual_rx_rate = usrp->get_rx_rate(); const double actual_tx_freq = usrp->get_tx_freq(); const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_tone_freq = actual_tx_freq + tx_wave_freq - actual_rx_freq; - const double bb_imag_freq = actual_tx_freq - tx_wave_freq - actual_rx_freq; + const double bb_tone_freq = actual_tx_freq + tx_wave_freq - actual_rx_freq; + const double bb_imag_freq = actual_tx_freq - tx_wave_freq - actual_rx_freq; - //reset TX IQ balance + // reset TX IQ balance usrp->set_tx_iq_balance(0.0); - //set optimal RX gain setting for this frequency + // set optimal RX gain setting for this frequency set_optimal_rx_gain(usrp, rx_stream, tx_wave_freq); - //capture initial uncorrected value + // capture initial uncorrected value capture_samples(usrp, rx_stream, buff, nsamps); - const double initial_suppression = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate) - compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double initial_suppression = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate) + - compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); - //bounds and results from searching + // bounds and results from searching double phase_corr_start = -1.0; - double phase_corr_stop = 1.0; - double phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + double phase_corr_stop = 1.0; + double phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); double ampl_corr_start = -1.0; - double ampl_corr_stop = 1.0; - double ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + double ampl_corr_stop = 1.0; + double ampl_corr_step = + (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); double best_suppression = 0; - double best_phase_corr = 0; - double best_ampl_corr = 0; - while (phase_corr_step >= precision or ampl_corr_step >= precision) - { - for (double phase_corr = phase_corr_start + phase_corr_step; phase_corr <= phase_corr_stop - phase_corr_step; phase_corr += phase_corr_step) - { - for (double ampl_corr = ampl_corr_start + ampl_corr_step; ampl_corr <= ampl_corr_stop - ampl_corr_step; ampl_corr += ampl_corr_step) - { + double best_phase_corr = 0; + double best_ampl_corr = 0; + while (phase_corr_step >= precision or ampl_corr_step >= precision) { + for (double phase_corr = phase_corr_start + phase_corr_step; + phase_corr <= phase_corr_stop - phase_corr_step; + phase_corr += phase_corr_step) { + for (double ampl_corr = ampl_corr_start + ampl_corr_step; + ampl_corr <= ampl_corr_stop - ampl_corr_step; + ampl_corr += ampl_corr_step) { const std::complex<double> correction(ampl_corr, phase_corr); usrp->set_tx_iq_balance(correction); - //receive some samples + // receive some samples capture_samples(usrp, rx_stream, buff, nsamps); - //check for TX errors in the current captured iteration - if (has_tx_error(tx_stream)){ - std::cout - << "[WARNING] TX error detected! " - << "Repeating current iteration" - << std::endl; + // check for TX errors in the current captured iteration + if (has_tx_error(tx_stream)) { + std::cout << "[WARNING] TX error detected! " + << "Repeating current iteration" << std::endl; // Undo ampl corr step ampl_corr -= ampl_corr_step; tx_error_count++; if (tx_error_count >= MAX_NUM_TX_ERRORS) { throw uhd::runtime_error( - "Too many TX errors. Aborting calibration." - ); + "Too many TX errors. Aborting calibration."); } continue; } - const double tone_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); - const double imag_dbrms = compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double tone_dbrms = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); + const double imag_dbrms = + compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); const double suppression = tone_dbrms - imag_dbrms; - if (suppression > best_suppression) - { + if (suppression > best_suppression) { best_suppression = suppression; - best_phase_corr = phase_corr; - best_ampl_corr = ampl_corr; + best_phase_corr = phase_corr; + best_ampl_corr = ampl_corr; } } } phase_corr_start = best_phase_corr - phase_corr_step; - phase_corr_stop = best_phase_corr + phase_corr_step; - phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + phase_corr_stop = best_phase_corr + phase_corr_step; + phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); ampl_corr_start = best_ampl_corr - ampl_corr_step; - ampl_corr_stop = best_ampl_corr + ampl_corr_step; - ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + ampl_corr_stop = best_ampl_corr + ampl_corr_step; + ampl_corr_step = (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); } - if (best_suppression > initial_suppression) //keep result + if (best_suppression > initial_suppression) // keep result { result_t result; - result.freq = tx_lo; + result.freq = tx_lo; result.real_corr = best_ampl_corr; result.imag_corr = best_phase_corr; - result.best = best_suppression; - result.delta = best_suppression - initial_suppression; + result.best = best_suppression; + result.delta = best_suppression - initial_suppression; results.push_back(result); if (vm.count("verbose")) - std::cout << boost::format("TX IQ: %f MHz: best suppression %f dB, corrected %f dB") % (tx_lo/1e6) % result.best % result.delta << std::endl; + std::cout << boost::format( + "TX IQ: %f MHz: best suppression %f dB, corrected %f dB") + % (tx_lo / 1e6) % result.best % result.delta + << std::endl; else std::cout << "." << std::flush; } @@ -276,13 +292,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } std::cout << std::endl; - //stop the transmitter + // stop the transmitter threads.interrupt_all(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); //wait for threads to finish + std::this_thread::sleep_for( + std::chrono::milliseconds(500)); // wait for threads to finish threads.join_all(); store_results(results, "TX", "tx", "iq", serial); return EXIT_SUCCESS; } - diff --git a/host/utils/uhd_config_info.cpp b/host/utils/uhd_config_info.cpp index 2c29af214..784ca9ff2 100644 --- a/host/utils/uhd_config_info.cpp +++ b/host/utils/uhd_config_info.cpp @@ -5,16 +5,16 @@ // #include <uhd/build_info.hpp> -#include <uhd/version.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/safe_main.hpp> - +#include <uhd/version.hpp> #include <boost/format.hpp> #include <boost/program_options.hpp> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char* argv[]) { +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ // Program Options po::options_description desc("Allowed Options"); // clang-format off @@ -42,51 +42,53 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) { po::notify(vm); // Print the help message - if(vm.count("help") > 0) { + if (vm.count("help") > 0) { std::cout << boost::format("UHD Config Info - %s") % desc << std::endl; return EXIT_FAILURE; } bool print_all = (vm.count("print-all") > 0); - if(vm.count("version") > 0 or print_all) { + if (vm.count("version") > 0 or print_all) { std::cout << "UHD " << uhd::get_version_string() << std::endl; } - if(vm.count("build-date") > 0 or print_all) { + if (vm.count("build-date") > 0 or print_all) { std::cout << "Build date: " << uhd::build_info::build_date() << std::endl; } - if(vm.count("c-compiler") > 0 or print_all) { + if (vm.count("c-compiler") > 0 or print_all) { std::cout << "C compiler: " << uhd::build_info::c_compiler() << std::endl; } - if(vm.count("cxx-compiler") > 0 or print_all) { + if (vm.count("cxx-compiler") > 0 or print_all) { std::cout << "C++ compiler: " << uhd::build_info::cxx_compiler() << std::endl; } - if(vm.count("c-flags") > 0 or print_all) { + if (vm.count("c-flags") > 0 or print_all) { std::cout << "C flags: " << uhd::build_info::c_flags() << std::endl; } - if(vm.count("cxx-flags") > 0 or print_all) { + if (vm.count("cxx-flags") > 0 or print_all) { std::cout << "C++ flags: " << uhd::build_info::cxx_flags() << std::endl; } - if(vm.count("enabled-components") > 0 or print_all) { - std::cout << "Enabled components: " << uhd::build_info::enabled_components() << std::endl; + if (vm.count("enabled-components") > 0 or print_all) { + std::cout << "Enabled components: " << uhd::build_info::enabled_components() + << std::endl; } - if(vm.count("install-prefix") > 0 or print_all) { + if (vm.count("install-prefix") > 0 or print_all) { std::cout << "Install prefix: " << uhd::build_info::install_prefix() << std::endl; } - if(vm.count("boost-version") > 0 or print_all) { + if (vm.count("boost-version") > 0 or print_all) { std::cout << "Boost version: " << uhd::build_info::boost_version() << std::endl; } - if(vm.count("libusb-version") > 0 or print_all) { + if (vm.count("libusb-version") > 0 or print_all) { std::string _libusb_version = uhd::build_info::libusb_version(); - std::cout << "Libusb version: " << (_libusb_version.empty() ? "N/A" : _libusb_version) << std::endl; + std::cout << "Libusb version: " + << (_libusb_version.empty() ? "N/A" : _libusb_version) << std::endl; } - if(vm.count("pkg-path") > 0 or print_all) { + if (vm.count("pkg-path") > 0 or print_all) { std::cout << "Package path: " << uhd::get_pkg_path() << std::endl; } - if(vm.count("images-dir") > 0 or print_all) { + if (vm.count("images-dir") > 0 or print_all) { std::cout << "Images directory: " << uhd::get_images_dir("") << std::endl; } - if(vm.count("abi-version") > 0 or print_all) { + if (vm.count("abi-version") > 0 or print_all) { std::cout << "ABI version string: " << uhd::get_abi_string() << std::endl; } diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp index 504fafcf7..ad30b168c 100644 --- a/host/utils/uhd_find_devices.cpp +++ b/host/utils/uhd_find_devices.cpp @@ -5,29 +5,30 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> #include <uhd/device.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/format.hpp> -#include <iostream> +#include <boost/program_options.hpp> #include <cstdlib> +#include <iostream> namespace { - //! Conditionally append find_all=1 if the key isn't there yet - uhd::device_addr_t append_findall(const uhd::device_addr_t& device_args) - { - uhd::device_addr_t new_device_args(device_args); - if (!new_device_args.has_key("find_all")) { - new_device_args["find_all"] = "1"; - } - - return new_device_args; +//! Conditionally append find_all=1 if the key isn't there yet +uhd::device_addr_t append_findall(const uhd::device_addr_t& device_args) +{ + uhd::device_addr_t new_device_args(device_args); + if (!new_device_args.has_key("find_all")) { + new_device_args["find_all"] = "1"; } + + return new_device_args; } +} // namespace namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -40,35 +41,34 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("UHD Find Devices %s") % desc << std::endl; return EXIT_SUCCESS; } - //discover the usrps and print the results + // discover the usrps and print the results const uhd::device_addr_t args(vm["args"].as<std::string>()); - uhd::device_addrs_t device_addrs = - uhd::device::find(append_findall(args)); + uhd::device_addrs_t device_addrs = uhd::device::find(append_findall(args)); if (device_addrs.empty()) { std::cerr << "No UHD Devices Found" << std::endl; return EXIT_FAILURE; } - typedef std::map<std::string, std::set<std::string> > device_multi_addrs_t; + typedef std::map<std::string, std::set<std::string>> device_multi_addrs_t; typedef std::map<std::string, device_multi_addrs_t> device_addrs_filtered_t; device_addrs_filtered_t found_devices; for (auto it = device_addrs.begin(); it != device_addrs.end(); ++it) { - std::string serial = (*it)["serial"]; + std::string serial = (*it)["serial"]; found_devices[serial] = device_multi_addrs_t(); - for(std::string key: it->keys()) { + for (std::string key : it->keys()) { if (key != "serial") { found_devices[serial][key].insert(it->get(key)); } } for (auto sit = it + 1; sit != device_addrs.end();) { if ((*sit)["serial"] == serial) { - for(std::string key: sit->keys()) { + for (std::string key : sit->keys()) { if (key != "serial") { found_devices[serial][key].insert(sit->get(key)); } @@ -82,19 +82,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ int i = 0; for (auto dit = found_devices.begin(); dit != found_devices.end(); ++dit) { - std::cout << "--------------------------------------------------" - << std::endl; + std::cout << "--------------------------------------------------" << std::endl; std::cout << "-- UHD Device " << i << std::endl; - std::cout << "--------------------------------------------------" - << std::endl; + std::cout << "--------------------------------------------------" << std::endl; std::stringstream ss; ss << "Device Address:" << std::endl; ss << boost::format(" serial: %s") % dit->first << std::endl; for (auto mit = dit->second.begin(); mit != dit->second.end(); ++mit) { - for (auto vit = mit->second.begin(); vit != mit->second.end(); - ++vit) { - ss << boost::format(" %s: %s") % mit->first % *vit - << std::endl; + for (auto vit = mit->second.begin(); vit != mit->second.end(); ++vit) { + ss << boost::format(" %s: %s") % mit->first % *vit << std::endl; } } std::cout << ss.str() << std::endl << std::endl; diff --git a/host/utils/uhd_image_loader.cpp b/host/utils/uhd_image_loader.cpp index 507a4ac87..57ad57958 100644 --- a/host/utils/uhd_image_loader.cpp +++ b/host/utils/uhd_image_loader.cpp @@ -5,47 +5,49 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <csignal> -#include <cstdlib> -#include <iostream> - -#include <boost/assign.hpp> -#include <boost/filesystem.hpp> -#include <boost/format.hpp> - #include <uhd/config.hpp> #include <uhd/image_loader.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/utils/safe_main.hpp> +#include <boost/assign.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> #include <boost/program_options.hpp> +#include <csignal> +#include <cstdlib> +#include <iostream> namespace fs = boost::filesystem; namespace po = boost::program_options; static std::string device_type = ""; -static int num_ctrl_c = 0; +static int num_ctrl_c = 0; /* * If the user presses Ctrl+C, warn them that they may corrupt their device. * If they press it again, provide instructions on restoring the device * (if applicable) and exit. */ -void sigint_handler(int){ +void sigint_handler(int) +{ num_ctrl_c++; - if(num_ctrl_c == 1){ + if (num_ctrl_c == 1) { std::cout << std::endl - << "Are you sure you want to abort? If you do, your device will likely" << std::endl + << "Are you sure you want to abort? If you do, your device will likely" + << std::endl << "be in an unstable or unusable state." << std::endl - << "Press Ctrl+C again to abort." << std::endl << std::endl; - } - else{ - std::cout << std::endl << uhd::image_loader::get_recovery_instructions(device_type) << std::endl; + << "Press Ctrl+C again to abort." << std::endl + << std::endl; + } else { + std::cout << std::endl + << uhd::image_loader::get_recovery_instructions(device_type) + << std::endl; exit(EXIT_FAILURE); } } -int UHD_SAFE_MAIN(int argc, char *argv[]){ - +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -65,10 +67,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::notify(vm); // Help message - if (vm.count("help")){ + if (vm.count("help")) { std::cout << "UHD Image Loader" << std::endl << std::endl - << "Load firmware and/or FPGA images onto an Ettus Research device." << std::endl + << "Load firmware and/or FPGA images onto an Ettus Research device." + << std::endl << std::endl << desc << std::endl; return EXIT_FAILURE; @@ -77,49 +80,50 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ // Convert user options uhd::image_loader::image_loader_args_t image_loader_args; image_loader_args.args = vm["args"].as<std::string>(); - image_loader_args.load_firmware = (vm.count("no-fw") == 0); - image_loader_args.load_fpga = (vm.count("no-fpga") == 0); + image_loader_args.load_firmware = (vm.count("no-fw") == 0); + image_loader_args.load_fpga = (vm.count("no-fpga") == 0); image_loader_args.download = (vm.count("download") != 0); image_loader_args.firmware_path = vm["fw-path"].as<std::string>(); image_loader_args.fpga_path = vm["fpga-path"].as<std::string>(); image_loader_args.out_path = vm["out-path"].as<std::string>(); // Force user to specify a device - if(not image_loader_args.args.has_key("type")){ + if (not image_loader_args.args.has_key("type")) { throw uhd::runtime_error("You must specify a device type."); } // Clean up paths, if given - if(image_loader_args.firmware_path != ""){ - #ifndef UHD_PLATFORM_WIN32 - if(image_loader_args.firmware_path.find("~") == 0){ - image_loader_args.firmware_path.replace(0,1,getenv("HOME")); + if (image_loader_args.firmware_path != "") { +#ifndef UHD_PLATFORM_WIN32 + if (image_loader_args.firmware_path.find("~") == 0) { + image_loader_args.firmware_path.replace(0, 1, getenv("HOME")); } - #endif /* UHD_PLATFORM_WIN32 */ - image_loader_args.firmware_path = fs::absolute(image_loader_args.firmware_path).string(); +#endif /* UHD_PLATFORM_WIN32 */ + image_loader_args.firmware_path = + fs::absolute(image_loader_args.firmware_path).string(); } - if(image_loader_args.fpga_path != ""){ - #ifndef UHD_PLATFORM_WIN32 - if(image_loader_args.fpga_path.find("~") == 0){ - image_loader_args.fpga_path.replace(0,1,getenv("HOME")); + if (image_loader_args.fpga_path != "") { +#ifndef UHD_PLATFORM_WIN32 + if (image_loader_args.fpga_path.find("~") == 0) { + image_loader_args.fpga_path.replace(0, 1, getenv("HOME")); } - #endif /* UHD_PLATFORM_WIN32 */ +#endif /* UHD_PLATFORM_WIN32 */ image_loader_args.fpga_path = fs::absolute(image_loader_args.fpga_path).string(); } - if(image_loader_args.out_path != ""){ - #ifndef UHD_PLATFORM_WIN32 - if(image_loader_args.out_path.find("~") == 0){ - image_loader_args.out_path.replace(0,1,getenv("HOME")); + if (image_loader_args.out_path != "") { +#ifndef UHD_PLATFORM_WIN32 + if (image_loader_args.out_path.find("~") == 0) { + image_loader_args.out_path.replace(0, 1, getenv("HOME")); } - #endif /* UHD_PLATFORM_WIN32 */ +#endif /* UHD_PLATFORM_WIN32 */ image_loader_args.out_path = fs::absolute(image_loader_args.out_path).string(); } // Detect which type of device we're working with - device_type = image_loader_args.args.get("type",""); + device_type = image_loader_args.args.get("type", ""); std::signal(SIGINT, &sigint_handler); - if(not uhd::image_loader::load(image_loader_args)){ + if (not uhd::image_loader::load(image_loader_args)) { std::cerr << "No applicable UHD devices found" << std::endl; return EXIT_FAILURE; } diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 3522b4148..8f60b211f 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -5,230 +5,303 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> -#include <uhd/version.hpp> #include <uhd/device.hpp> #include <uhd/device3.hpp> -#include <uhd/types/ranges.hpp> #include <uhd/property_tree.hpp> -#include <boost/algorithm/string.hpp> //for split +#include <uhd/types/ranges.hpp> +#include <uhd/types/sensors.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/dboard_id.hpp> #include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/types/sensors.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/version.hpp> +#include <boost/algorithm/string.hpp> //for split #include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <cstdlib> #include <iostream> #include <sstream> #include <vector> -#include <cstdlib> namespace po = boost::program_options; using namespace uhd; -static std::string make_border(const std::string &text){ +static std::string make_border(const std::string& text) +{ std::stringstream ss; - ss << boost::format(" _____________________________________________________") << std::endl; + ss << boost::format(" _____________________________________________________") + << std::endl; ss << boost::format(" /") << std::endl; - std::vector<std::string> lines; boost::split(lines, text, boost::is_any_of("\n")); - while (lines.back().empty()) lines.pop_back(); //strip trailing newlines - if (lines.size()) lines[0] = " " + lines[0]; //indent the title line - for(const std::string &line: lines){ + std::vector<std::string> lines; + boost::split(lines, text, boost::is_any_of("\n")); + while (lines.back().empty()) + lines.pop_back(); // strip trailing newlines + if (lines.size()) + lines[0] = " " + lines[0]; // indent the title line + for (const std::string& line : lines) { ss << boost::format("| %s") % line << std::endl; } - //ss << boost::format(" \\_____________________________________________________") << std::endl; + // ss << boost::format(" \\_____________________________________________________") << + // std::endl; return ss.str(); } -static std::string get_dsp_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_dsp_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << boost::format("%s DSP: %s") % type % path.leaf() << std::endl; ss << std::endl; meta_range_t freq_range = tree->access<meta_range_t>(path / "freq/range").get(); - ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl;; + ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start() / 1e6) + % (freq_range.stop() / 1e6) + << std::endl; + ; return ss.str(); } -static std::string prop_names_to_pp_string(const std::vector<std::string> &prop_names){ - std::stringstream ss; size_t count = 0; - for(const std::string &prop_name: prop_names){ - ss << ((count++)? ", " : "") << prop_name; +static std::string prop_names_to_pp_string(const std::vector<std::string>& prop_names) +{ + std::stringstream ss; + size_t count = 0; + for (const std::string& prop_name : prop_names) { + ss << ((count++) ? ", " : "") << prop_name; } return ss.str(); } -static std::string get_frontend_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_frontend_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << boost::format("%s Frontend: %s") % type % path.leaf() << std::endl; - //ss << std::endl; + // ss << std::endl; - ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) << std::endl; - ss << boost::format("Antennas: %s") % prop_names_to_pp_string(tree->access<std::vector<std::string> >(path / "antenna/options").get()) << std::endl; - if (tree->exists(path/ "sensors")) { - ss << boost::format("Sensors: %s") % prop_names_to_pp_string(tree->list(path / "sensors")) << std::endl; + ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) + << std::endl; + ss << boost::format("Antennas: %s") + % prop_names_to_pp_string( + tree->access<std::vector<std::string>>(path / "antenna/options") + .get()) + << std::endl; + if (tree->exists(path / "sensors")) { + ss << boost::format("Sensors: %s") + % prop_names_to_pp_string(tree->list(path / "sensors")) + << std::endl; } meta_range_t freq_range = tree->access<meta_range_t>(path / "freq/range").get(); - ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl; + ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start() / 1e6) + % (freq_range.stop() / 1e6) + << std::endl; std::vector<std::string> gain_names = tree->list(path / "gains"); - if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; - for(const std::string &name: gain_names){ - meta_range_t gain_range = tree->access<meta_range_t>(path / "gains" / name / "range").get(); - ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; + if (gain_names.size() == 0) + ss << "Gain Elements: None" << std::endl; + for (const std::string& name : gain_names) { + meta_range_t gain_range = + tree->access<meta_range_t>(path / "gains" / name / "range").get(); + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name + % gain_range.start() % gain_range.stop() % gain_range.step() + << std::endl; } - if (tree->exists(path / "bandwidth" / "range")) - { - meta_range_t bw_range = tree->access<meta_range_t>(path / "bandwidth" / "range").get(); - ss << boost::format("Bandwidth range: %.1f to %.1f step %.1f Hz") % bw_range.start() % bw_range.stop() % bw_range.step() << std::endl; + if (tree->exists(path / "bandwidth" / "range")) { + meta_range_t bw_range = + tree->access<meta_range_t>(path / "bandwidth" / "range").get(); + ss << boost::format("Bandwidth range: %.1f to %.1f step %.1f Hz") + % bw_range.start() % bw_range.stop() % bw_range.step() + << std::endl; } - ss << boost::format("Connection Type: %s") % (tree->access<std::string>(path / "connection").get()) << std::endl; + ss << boost::format("Connection Type: %s") + % (tree->access<std::string>(path / "connection").get()) + << std::endl; ss << boost::format("Uses LO offset: %s") - % ((tree->exists(path / "use_lo_offset") and tree->access<bool>(path / "use_lo_offset").get())? "Yes" : "No") + % ((tree->exists(path / "use_lo_offset") + and tree->access<bool>(path / "use_lo_offset").get()) + ? "Yes" + : "No") << std::endl; return ss.str(); } -static std::string get_codec_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_codec_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; if (tree->exists(path / "name")) { ss << boost::format("%s Codec: %s") % type % path.leaf() << std::endl; - ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) << std::endl; + ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) + << std::endl; std::vector<std::string> gain_names = tree->list(path / "gains"); - if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; - for(const std::string &name: gain_names){ - meta_range_t gain_range = tree->access<meta_range_t>(path / "gains" / name / "range").get(); - ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; + if (gain_names.size() == 0) + ss << "Gain Elements: None" << std::endl; + for (const std::string& name : gain_names) { + meta_range_t gain_range = + tree->access<meta_range_t>(path / "gains" / name / "range").get(); + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name + % gain_range.start() % gain_range.stop() % gain_range.step() + << std::endl; } } return ss.str(); } -static std::string get_dboard_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_dboard_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << boost::format("%s Dboard: %s") % type % path.leaf() << std::endl; - //ss << std::endl; - const std::string prefix = (type == "RX")? "rx" : "tx"; - if (tree->exists(path / (prefix + "_eeprom"))) - { - usrp::dboard_eeprom_t db_eeprom = tree->access<usrp::dboard_eeprom_t>(path / (prefix + "_eeprom")).get(); - if (db_eeprom.id != usrp::dboard_id_t::none()) ss << boost::format("ID: %s") % db_eeprom.id.to_pp_string() << std::endl; - if (not db_eeprom.serial.empty()) ss << boost::format("Serial: %s") % db_eeprom.serial << std::endl; - if (type == "TX"){ - usrp::dboard_eeprom_t gdb_eeprom = tree->access<usrp::dboard_eeprom_t>(path / "gdb_eeprom").get(); - if (gdb_eeprom.id != usrp::dboard_id_t::none()) ss << boost::format("ID: %s") % gdb_eeprom.id.to_pp_string() << std::endl; - if (not gdb_eeprom.serial.empty()) ss << boost::format("Serial: %s") % gdb_eeprom.serial << std::endl; + // ss << std::endl; + const std::string prefix = (type == "RX") ? "rx" : "tx"; + if (tree->exists(path / (prefix + "_eeprom"))) { + usrp::dboard_eeprom_t db_eeprom = + tree->access<usrp::dboard_eeprom_t>(path / (prefix + "_eeprom")).get(); + if (db_eeprom.id != usrp::dboard_id_t::none()) + ss << boost::format("ID: %s") % db_eeprom.id.to_pp_string() << std::endl; + if (not db_eeprom.serial.empty()) + ss << boost::format("Serial: %s") % db_eeprom.serial << std::endl; + if (type == "TX") { + usrp::dboard_eeprom_t gdb_eeprom = + tree->access<usrp::dboard_eeprom_t>(path / "gdb_eeprom").get(); + if (gdb_eeprom.id != usrp::dboard_id_t::none()) + ss << boost::format("ID: %s") % gdb_eeprom.id.to_pp_string() << std::endl; + if (not gdb_eeprom.serial.empty()) + ss << boost::format("Serial: %s") % gdb_eeprom.serial << std::endl; } } if (tree->exists(path / (prefix + "_frontends"))) { - for(const std::string &name: tree->list(path / (prefix + "_frontends"))){ - ss << make_border(get_frontend_pp_string(type, tree, path / (prefix + "_frontends") / name)); + for (const std::string& name : tree->list(path / (prefix + "_frontends"))) { + ss << make_border(get_frontend_pp_string( + type, tree, path / (prefix + "_frontends") / name)); } } - ss << make_border(get_codec_pp_string(type, tree, path.branch_path().branch_path() / (prefix + "_codecs") / path.leaf())); + ss << make_border(get_codec_pp_string(type, + tree, + path.branch_path().branch_path() / (prefix + "_codecs") / path.leaf())); return ss.str(); } -static std::string get_rfnoc_pp_string(property_tree::sptr tree, const fs_path &path){ +static std::string get_rfnoc_pp_string(property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << "RFNoC blocks on this device:" << std::endl << std::endl; - for(const std::string &name: tree->list(path)){ + for (const std::string& name : tree->list(path)) { ss << "* " << name << std::endl; } return ss.str(); } -static std::string get_mboard_pp_string(property_tree::sptr tree, const fs_path &path){ +static std::string get_mboard_pp_string(property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; - ss << boost::format("Mboard: %s") % (tree->access<std::string>(path / "name").get()) << std::endl; + ss << boost::format("Mboard: %s") % (tree->access<std::string>(path / "name").get()) + << std::endl; - if (tree->exists(path / "eeprom")){ - usrp::mboard_eeprom_t mb_eeprom = tree->access<usrp::mboard_eeprom_t>(path / "eeprom").get(); - for(const std::string &key: mb_eeprom.keys()){ - if (not mb_eeprom[key].empty()) ss << boost::format("%s: %s") % key % mb_eeprom[key] << std::endl; + if (tree->exists(path / "eeprom")) { + usrp::mboard_eeprom_t mb_eeprom = + tree->access<usrp::mboard_eeprom_t>(path / "eeprom").get(); + for (const std::string& key : mb_eeprom.keys()) { + if (not mb_eeprom[key].empty()) + ss << boost::format("%s: %s") % key % mb_eeprom[key] << std::endl; } } else { ss << "No mboard EEPROM found." << std::endl; } - if (tree->exists(path / "fw_version")){ - ss << "FW Version: " << tree->access<std::string>(path / "fw_version").get() << std::endl; + if (tree->exists(path / "fw_version")) { + ss << "FW Version: " << tree->access<std::string>(path / "fw_version").get() + << std::endl; } - if (tree->exists(path / "mpm_version")){ - ss << "MPM Version: " << tree->access<std::string>(path / "mpm_version").get() << std::endl; + if (tree->exists(path / "mpm_version")) { + ss << "MPM Version: " << tree->access<std::string>(path / "mpm_version").get() + << std::endl; } - if (tree->exists(path / "fpga_version")){ - ss << "FPGA Version: " << tree->access<std::string>(path / "fpga_version").get() << std::endl; + if (tree->exists(path / "fpga_version")) { + ss << "FPGA Version: " << tree->access<std::string>(path / "fpga_version").get() + << std::endl; } - if (tree->exists(path / "fpga_version_hash")){ - ss << "FPGA git hash: " << tree->access<std::string>(path / "fpga_version_hash").get() << std::endl; + if (tree->exists(path / "fpga_version_hash")) { + ss << "FPGA git hash: " + << tree->access<std::string>(path / "fpga_version_hash").get() << std::endl; } - if (tree->exists(path / "xbar")){ + if (tree->exists(path / "xbar")) { ss << "RFNoC capable: Yes" << std::endl; } ss << std::endl; try { - if (tree->exists(path / "time_source" / "options")){ - const std::vector< std::string > time_sources = tree->access<std::vector<std::string> >(path / "time_source" / "options").get(); - ss << "Time sources: " << prop_names_to_pp_string(time_sources) << std::endl; + if (tree->exists(path / "time_source" / "options")) { + const std::vector<std::string> time_sources = + tree->access<std::vector<std::string>>(path / "time_source" / "options") + .get(); + ss << "Time sources: " << prop_names_to_pp_string(time_sources) << std::endl; } - if (tree->exists(path / "clock_source" / "options")){ - const std::vector< std::string > clock_sources = tree->access<std::vector<std::string> >(path / "clock_source" / "options").get(); - ss << "Clock sources: " << prop_names_to_pp_string(clock_sources) << std::endl; + if (tree->exists(path / "clock_source" / "options")) { + const std::vector<std::string> clock_sources = + tree->access<std::vector<std::string>>(path / "clock_source" / "options") + .get(); + ss << "Clock sources: " << prop_names_to_pp_string(clock_sources) + << std::endl; } - if (tree->exists(path / "sensors")){ - ss << "Sensors: " << prop_names_to_pp_string(tree->list(path / "sensors")) << std::endl; + if (tree->exists(path / "sensors")) { + ss << "Sensors: " << prop_names_to_pp_string(tree->list(path / "sensors")) + << std::endl; } - if (tree->exists(path / "rx_dsps")){ - for(const std::string &name: tree->list(path / "rx_dsps")){ + if (tree->exists(path / "rx_dsps")) { + for (const std::string& name : tree->list(path / "rx_dsps")) { ss << make_border(get_dsp_pp_string("RX", tree, path / "rx_dsps" / name)); } } if (tree->exists(path / "dboards")) { - for(const std::string &name: tree->list(path / "dboards")){ - ss << make_border(get_dboard_pp_string("RX", tree, path / "dboards" / name)); + for (const std::string& name : tree->list(path / "dboards")) { + ss << make_border( + get_dboard_pp_string("RX", tree, path / "dboards" / name)); } - if (tree->exists(path / "tx_dsps")){ - for(const std::string &name: tree->list(path / "tx_dsps")){ - ss << make_border(get_dsp_pp_string("TX", tree, path / "tx_dsps" / name)); + if (tree->exists(path / "tx_dsps")) { + for (const std::string& name : tree->list(path / "tx_dsps")) { + ss << make_border( + get_dsp_pp_string("TX", tree, path / "tx_dsps" / name)); } } - for(const std::string &name: tree->list(path / "dboards")){ - ss << make_border(get_dboard_pp_string("TX", tree, path / "dboards" / name)); + for (const std::string& name : tree->list(path / "dboards")) { + ss << make_border( + get_dboard_pp_string("TX", tree, path / "dboards" / name)); } } - if (tree->exists(path / "xbar")){ + if (tree->exists(path / "xbar")) { ss << make_border(get_rfnoc_pp_string(tree, path / "xbar")); } - } - catch (const uhd::lookup_error& ex) { + } catch (const uhd::lookup_error& ex) { std::cout << "Exited device probe on " << ex.what() << std::endl; } return ss.str(); } -static std::string get_device_pp_string(property_tree::sptr tree){ +static std::string get_device_pp_string(property_tree::sptr tree) +{ std::stringstream ss; - ss << boost::format("Device: %s") % (tree->access<std::string>("/name").get()) << std::endl; - //ss << std::endl; - for(const std::string &name: tree->list("/mboards")){ + ss << boost::format("Device: %s") % (tree->access<std::string>("/name").get()) + << std::endl; + // ss << std::endl; + for (const std::string& name : tree->list("/mboards")) { ss << make_border(get_mboard_pp_string(tree, "/mboards/" + name)); } return ss.str(); } -void print_tree(const uhd::fs_path &path, uhd::property_tree::sptr tree){ +void print_tree(const uhd::fs_path& path, uhd::property_tree::sptr tree) +{ std::cout << path << std::endl; - for(const std::string &name: tree->list(path)){ + for (const std::string& name : tree->list(path)) { print_tree(path / name, tree); } } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -250,57 +323,69 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("UHD USRP Probe %s") % desc << std::endl; return EXIT_FAILURE; } - if (vm.count("version")){ + if (vm.count("version")) { std::cout << uhd::get_version_string() << std::endl; return EXIT_SUCCESS; } - device::sptr dev = device::make(vm["args"].as<std::string>()); + device::sptr dev = device::make(vm["args"].as<std::string>()); property_tree::sptr tree = dev->get_tree(); - if (vm.count("string")){ + if (vm.count("string")) { if (vm.count("vector")) { - std::vector<std::string> str_vector = tree->access< std::vector<std::string> >(vm["string"].as<std::string>()).get(); + std::vector<std::string> str_vector = + tree->access<std::vector<std::string>>(vm["string"].as<std::string>()) + .get(); std::cout << "("; - for(const std::string &str: str_vector) { + for (const std::string& str : str_vector) { std::cout << str << ","; } std::cout << ")" << std::endl; } else { - std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() << std::endl; + std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() + << std::endl; } return EXIT_SUCCESS; } - if (vm.count("double")){ - std::cout << tree->access<double>(vm["double"].as<std::string>()).get() << std::endl; + if (vm.count("double")) { + std::cout << tree->access<double>(vm["double"].as<std::string>()).get() + << std::endl; return EXIT_SUCCESS; } - if (vm.count("int")){ + if (vm.count("int")) { std::cout << tree->access<int>(vm["int"].as<std::string>()).get() << std::endl; return EXIT_SUCCESS; } - if (vm.count("sensor")){ - std::cout << tree->access<uhd::sensor_value_t>(vm["sensor"].as<std::string>()).get().value << std::endl; + if (vm.count("sensor")) { + std::cout << tree->access<uhd::sensor_value_t>(vm["sensor"].as<std::string>()) + .get() + .value + << std::endl; return EXIT_SUCCESS; } - if (vm.count("range")){ - meta_range_t range = tree->access<meta_range_t>(vm["range"].as<std::string>()).get(); - std::cout << boost::format("%.1f:%.1f:%.1f") % range.start() % range.step() % range.stop() << std::endl; + if (vm.count("range")) { + meta_range_t range = + tree->access<meta_range_t>(vm["range"].as<std::string>()).get(); + std::cout << boost::format("%.1f:%.1f:%.1f") % range.start() % range.step() + % range.stop() + << std::endl; return EXIT_SUCCESS; } - if (vm.count("tree") != 0) print_tree("/", tree); - else if (not vm.count("init-only")) std::cout << make_border(get_device_pp_string(tree)) << std::endl; + if (vm.count("tree") != 0) + print_tree("/", tree); + else if (not vm.count("init-only")) + std::cout << make_border(get_device_pp_string(tree)) << std::endl; return EXIT_SUCCESS; } diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp index 391c35950..cfb80fd42 100644 --- a/host/utils/usrp_burn_db_eeprom.cpp +++ b/host/utils/usrp_burn_db_eeprom.cpp @@ -6,24 +6,25 @@ // -#include <uhd/utils/safe_main.hpp> #include <uhd/device.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/utils/assert_has.hpp> #include <uhd/property_tree.hpp> +#include <uhd/types/dict.hpp> #include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> #include <boost/assign.hpp> +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> using namespace uhd; using namespace uhd::usrp; namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ - //command line variables +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ + // command line variables std::string args, slot, unit; po::options_description desc("Allowed options"); @@ -43,49 +44,54 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ - std::cout << boost::format("USRP Burn Daughterboard EEPROM %s") % desc << std::endl; - std::cout << boost::format( - "Omit the ID argument to perform readback,\n" - "Or specify a new ID to burn into the EEPROM.\n" - ) << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Burn Daughterboard EEPROM %s") % desc + << std::endl; + std::cout << boost::format("Omit the ID argument to perform readback,\n" + "Or specify a new ID to burn into the EEPROM.\n") + << std::endl; return EXIT_FAILURE; } - //make the device and extract the dboard w/ property - device::sptr dev = device::make(args, device::USRP); - uhd::property_tree::sptr tree = dev->get_tree(); - const uhd::fs_path db_root = "/mboards/0/dboards"; + // make the device and extract the dboard w/ property + device::sptr dev = device::make(args, device::USRP); + uhd::property_tree::sptr tree = dev->get_tree(); + const uhd::fs_path db_root = "/mboards/0/dboards"; std::vector<std::string> dboard_names = tree->list(db_root); - if (dboard_names.size() == 1 and slot.empty()) slot = dboard_names.front(); + if (dboard_names.size() == 1 and slot.empty()) + slot = dboard_names.front(); uhd::assert_has(dboard_names, slot, "dboard slot name"); - std::cout << boost::format("Reading %s EEPROM on %s dboard...") % unit % slot << std::endl; + std::cout << boost::format("Reading %s EEPROM on %s dboard...") % unit % slot + << std::endl; boost::to_lower(unit); const uhd::fs_path db_path = db_root / slot / (unit + "_eeprom"); - dboard_eeprom_t db_eeprom = tree->access<dboard_eeprom_t>(db_path).get(); + dboard_eeprom_t db_eeprom = tree->access<dboard_eeprom_t>(db_path).get(); //------------- handle the dboard ID -----------------------------// - if (vm.count("id")){ + if (vm.count("id")) { db_eeprom.id = dboard_id_t::from_string(vm["id"].as<std::string>()); tree->access<dboard_eeprom_t>(db_path).set(db_eeprom); } - std::cout << boost::format(" Current ID: %s") % db_eeprom.id.to_pp_string() << std::endl; + std::cout << boost::format(" Current ID: %s") % db_eeprom.id.to_pp_string() + << std::endl; //------------- handle the dboard serial--------------------------// - if (vm.count("ser")){ + if (vm.count("ser")) { db_eeprom.serial = vm["ser"].as<std::string>(); tree->access<dboard_eeprom_t>(db_path).set(db_eeprom); } - std::cout << boost::format(" Current serial: \"%s\"") % db_eeprom.serial << std::endl; + std::cout << boost::format(" Current serial: \"%s\"") % db_eeprom.serial + << std::endl; //------------- handle the dboard revision------------------------// - if (vm.count("rev")){ + if (vm.count("rev")) { db_eeprom.revision = vm["rev"].as<std::string>(); tree->access<dboard_eeprom_t>(db_path).set(db_eeprom); } - std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision << std::endl; + std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision + << std::endl; std::cout << " Done" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/utils/usrp_burn_mb_eeprom.cpp b/host/utils/usrp_burn_mb_eeprom.cpp index e2596d5c4..65b68f379 100644 --- a/host/utils/usrp_burn_mb_eeprom.cpp +++ b/host/utils/usrp_burn_mb_eeprom.cpp @@ -5,20 +5,21 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> #include <uhd/device.hpp> #include <uhd/property_tree.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/types/device_addr.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string.hpp> -#include <boost/program_options.hpp> #include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> #include <vector> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ std::string args, input_str; po::options_description desc("Allowed options"); @@ -35,28 +36,31 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))){ + // print the help message + if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))) { std::cout << boost::format("USRP Burn Motherboard EEPROM %s") % desc << std::endl; - std::cout << boost::format( - "Omit the value argument to perform a readback,\n" - "Or specify a new value to burn into the EEPROM.\n" - "Example (write to ip-addr0 and read out ip-addr1):\n" - " usrp_burn_mb_eeprom --args=<device args> --values\"ip-addr0=192.168.10.3,ip-addr1\"" - ) << std::endl; + std::cout << boost::format("Omit the value argument to perform a readback,\n" + "Or specify a new value to burn into the EEPROM.\n" + "Example (write to ip-addr0 and read out ip-addr1):\n" + " usrp_burn_mb_eeprom --args=<device args> " + "--values\"ip-addr0=192.168.10.3,ip-addr1\"") + << std::endl; return EXIT_FAILURE; } std::cout << "Creating USRP device from address: " + args << std::endl; - uhd::device::sptr dev = uhd::device::make(args, uhd::device::USRP); + uhd::device::sptr dev = uhd::device::make(args, uhd::device::USRP); uhd::property_tree::sptr tree = dev->get_tree(); - uhd::usrp::mboard_eeprom_t mb_eeprom = tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get(); + uhd::usrp::mboard_eeprom_t mb_eeprom = + tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get(); std::cout << std::endl; std::vector<std::string> keys_vec, vals_vec; - if(vm.count("read-all")) keys_vec = mb_eeprom.keys(); //Leaving vals_vec empty will force utility to only read - else if(vm.count("values")){ - //uhd::device_addr_t properly parses input values + if (vm.count("read-all")) + keys_vec = + mb_eeprom.keys(); // Leaving vals_vec empty will force utility to only read + else if (vm.count("values")) { + // uhd::device_addr_t properly parses input values uhd::device_addr_t vals(input_str); keys_vec = vals.keys(); vals_vec = vals.vals(); @@ -64,25 +68,31 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ // 1. Read out values std::cout << "Fetching current settings from EEPROM..." << std::endl; - for(size_t i = 0; i < keys_vec.size(); i++){ - if (not mb_eeprom.has_key(keys_vec[i])){ - std::cerr << boost::format("Cannot find value for EEPROM[%s]") % keys_vec[i] << std::endl; + for (size_t i = 0; i < keys_vec.size(); i++) { + if (not mb_eeprom.has_key(keys_vec[i])) { + std::cerr << boost::format("Cannot find value for EEPROM[%s]") % keys_vec[i] + << std::endl; return EXIT_FAILURE; } - std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] % mb_eeprom[keys_vec[i]] << std::endl; + std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] + % mb_eeprom[keys_vec[i]] + << std::endl; } std::cout << std::endl; // 2. Write new values if given mb_eeprom = uhd::usrp::mboard_eeprom_t(); - for(size_t i = 0; i < vals_vec.size(); i++){ - if(vals_vec[i] != ""){ + for (size_t i = 0; i < vals_vec.size(); i++) { + if (vals_vec[i] != "") { mb_eeprom[keys_vec[i]] = vals_vec[i]; - std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") % keys_vec[i] % vals_vec[i] << std::endl; + std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") + % keys_vec[i] % vals_vec[i] + << std::endl; } } tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").set(mb_eeprom); - std::cout << "Power-cycle the USRP device for the changes to take effect." << std::endl; + std::cout << "Power-cycle the USRP device for the changes to take effect." + << std::endl; std::cout << std::endl; std::cout << "Done" << std::endl; diff --git a/host/utils/usrp_cal_utils.hpp b/host/utils/usrp_cal_utils.hpp index ebd1400b7..fe567c7de 100644 --- a/host/utils/usrp_cal_utils.hpp +++ b/host/utils/usrp_cal_utils.hpp @@ -5,38 +5,40 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/paths.hpp> #include <uhd/property_tree.hpp> -#include <uhd/usrp/multi_usrp.hpp> #include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/utils/paths.hpp> +#include <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> #include <boost/filesystem.hpp> #include <boost/format.hpp> -#include <iostream> -#include <vector> -#include <complex> +#include <chrono> #include <cmath> +#include <complex> #include <cstdlib> #include <fstream> -#include <chrono> +#include <iostream> #include <thread> +#include <vector> namespace fs = boost::filesystem; -struct result_t{double freq, real_corr, imag_corr, best, delta;}; +struct result_t +{ + double freq, real_corr, imag_corr, best, delta; +}; typedef std::complex<float> samp_type; /*********************************************************************** * Constants **********************************************************************/ -static const double tau = 6.28318531; -static const size_t wave_table_len = 65536; -static const size_t num_search_steps = 5; -static const double default_precision = 0.0001; -static const double default_freq_step = 7.3e6; -static const size_t default_fft_bin_size = 1000; +static const double tau = 6.28318531; +static const size_t wave_table_len = 65536; +static const size_t num_search_steps = 5; +static const double default_precision = 0.0001; +static const double default_freq_step = 7.3e6; +static const size_t default_fft_bin_size = 1000; static constexpr size_t MAX_NUM_TX_ERRORS = 10; /*********************************************************************** @@ -49,51 +51,44 @@ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp) uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); const uhd::fs_path mb_path = "/mboards/0"; - const std::string mb_name = tree->access<std::string>(mb_path / "name").get(); - if (mb_name.find("USRP2") != std::string::npos or - mb_name.find("N200") != std::string::npos or - mb_name.find("N210") != std::string::npos or - mb_name.find("X300") != std::string::npos or - mb_name.find("X310") != std::string::npos or - mb_name.find("n3xx") != std::string::npos) - { + const std::string mb_name = tree->access<std::string>(mb_path / "name").get(); + if (mb_name.find("USRP2") != std::string::npos + or mb_name.find("N200") != std::string::npos + or mb_name.find("N210") != std::string::npos + or mb_name.find("X300") != std::string::npos + or mb_name.find("X310") != std::string::npos + or mb_name.find("n3xx") != std::string::npos) { usrp->set_tx_rate(12.5e6); usrp->set_rx_rate(12.5e6); - } - else if (mb_name.find("B100") != std::string::npos) - { + } else if (mb_name.find("B100") != std::string::npos) { usrp->set_tx_rate(4e6); usrp->set_rx_rate(4e6); - } - else - { + } else { throw std::runtime_error("self-calibration is not supported for this device"); } - const uhd::fs_path tx_fe_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/tx_frontends/0"; + const uhd::fs_path tx_fe_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/tx_frontends/0"; const std::string tx_name = tree->access<std::string>(tx_fe_path / "name").get(); - if (tx_name.find("WBX") == std::string::npos and - tx_name.find("SBX") == std::string::npos and - tx_name.find("CBX") == std::string::npos and - tx_name.find("RFX") == std::string::npos and - tx_name.find("UBX") == std::string::npos and - tx_name.find("Rhodium") == std::string::npos - ) - { + if (tx_name.find("WBX") == std::string::npos + and tx_name.find("SBX") == std::string::npos + and tx_name.find("CBX") == std::string::npos + and tx_name.find("RFX") == std::string::npos + and tx_name.find("UBX") == std::string::npos + and tx_name.find("Rhodium") == std::string::npos) { throw std::runtime_error("self-calibration is not supported for this TX dboard"); } usrp->set_tx_gain(0); - const uhd::fs_path rx_fe_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_frontends/0"; + const uhd::fs_path rx_fe_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_frontends/0"; const std::string rx_name = tree->access<std::string>(rx_fe_path / "name").get(); - if (rx_name.find("WBX") == std::string::npos and - rx_name.find("SBX") == std::string::npos and - rx_name.find("CBX") == std::string::npos and - rx_name.find("RFX") == std::string::npos and - rx_name.find("UBX") == std::string::npos and - rx_name.find("Rhodium") == std::string::npos - ) - { + if (rx_name.find("WBX") == std::string::npos + and rx_name.find("SBX") == std::string::npos + and rx_name.find("CBX") == std::string::npos + and rx_name.find("RFX") == std::string::npos + and rx_name.find("UBX") == std::string::npos + and rx_name.find("Rhodium") == std::string::npos) { throw std::runtime_error("self-calibration is not supported for this RX dboard"); } usrp->set_rx_gain(0); @@ -107,13 +102,16 @@ void check_for_empty_serial(uhd::usrp::multi_usrp::sptr usrp) // Will work on 1st subdev, top-level must make sure it's the right one uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); - //extract eeprom + // extract eeprom uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // This only works with transceiver boards, so we can always check rx side - const uhd::fs_path db_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_eeprom"; - const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); + const uhd::fs_path db_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_eeprom"; + const uhd::usrp::dboard_eeprom_t db_eeprom = + tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); - std::string error_string = "This dboard has no serial!\n\nPlease see the Calibration documentation for details on how to fix this."; + std::string error_string = "This dboard has no serial!\n\nPlease see the Calibration " + "documentation for details on how to fix this."; if (db_eeprom.serial.empty()) throw std::runtime_error(error_string); } @@ -128,7 +126,7 @@ public: { _table.resize(wave_table_len); for (size_t i = 0; i < wave_table_len; i++) - _table[i] = samp_type(std::polar(ampl, (tau*i)/wave_table_len)); + _table[i] = samp_type(std::polar(ampl, (tau * i) / wave_table_len)); } inline samp_type operator()(const size_t index) const @@ -137,33 +135,32 @@ public: } private: - std::vector<samp_type > _table; + std::vector<samp_type> _table; }; /*********************************************************************** * Compute power of a tone **********************************************************************/ -static inline double compute_tone_dbrms( - const std::vector<samp_type> &samples, - const double freq) //freq is fractional +static inline double compute_tone_dbrms(const std::vector<samp_type>& samples, + const double freq) // freq is fractional { - //shift the samples so the tone at freq is down at DC - //and average the samples to measure the DC component + // shift the samples so the tone at freq is down at DC + // and average the samples to measure the DC component samp_type average = 0; for (size_t i = 0; i < samples.size(); i++) - average += samp_type(std::polar(1.0, -freq*tau*i)) * samples[i]; + average += samp_type(std::polar(1.0, -freq * tau * i)) * samples[i]; - return 20*std::log10(std::abs(average/float(samples.size()))); + return 20 * std::log10(std::abs(average / float(samples.size()))); } /*********************************************************************** * Write a dat file **********************************************************************/ static inline void write_samples_to_file( - const std::vector<samp_type > &samples, const std::string &file) + const std::vector<samp_type>& samples, const std::string& file) { std::ofstream outfile(file.c_str(), std::ofstream::binary); - outfile.write((const char*)&samples.front(), samples.size()*sizeof(samp_type)); + outfile.write((const char*)&samples.front(), samples.size() * sizeof(samp_type)); outfile.close(); } @@ -171,38 +168,39 @@ static inline void write_samples_to_file( /*********************************************************************** * Retrieve d'board serial **********************************************************************/ -static std::string get_serial( - uhd::usrp::multi_usrp::sptr usrp, - const std::string &tx_rx) +static std::string get_serial(uhd::usrp::multi_usrp::sptr usrp, const std::string& tx_rx) { uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // Will work on 1st subdev, top-level must make sure it's the right one uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); - const uhd::fs_path db_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/" + tx_rx + "_eeprom"; - const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); + const uhd::fs_path db_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/" + tx_rx + "_eeprom"; + const uhd::usrp::dboard_eeprom_t db_eeprom = + tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); return db_eeprom.serial; } /*********************************************************************** * Store data to file **********************************************************************/ -static void store_results( - const std::vector<result_t> &results, - const std::string &XX, // "TX" or "RX" - const std::string &xx, // "tx" or "rx" - const std::string &what, // Type of test, e.g. "iq", - const std::string &serial) +static void store_results(const std::vector<result_t>& results, + const std::string& XX, // "TX" or "RX" + const std::string& xx, // "tx" or "rx" + const std::string& what, // Type of test, e.g. "iq", + const std::string& serial) { - //make the calibration file path + // make the calibration file path fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd"; fs::create_directory(cal_data_path); cal_data_path = cal_data_path / "cal"; fs::create_directory(cal_data_path); - cal_data_path = cal_data_path / str(boost::format("%s_%s_cal_v0.2_%s.csv") % xx % what % serial); + cal_data_path = + cal_data_path / str(boost::format("%s_%s_cal_v0.2_%s.csv") % xx % what % serial); if (fs::exists(cal_data_path)) - fs::rename(cal_data_path, cal_data_path.string() + str(boost::format(".%d") % time(NULL))); + fs::rename(cal_data_path, + cal_data_path.string() + str(boost::format(".%d") % time(NULL))); - //fill the calibration file + // fill the calibration file std::ofstream cal_data(cal_data_path.string().c_str()); cal_data << boost::format("name, %s Frontend Calibration\n") % XX; cal_data << boost::format("serial, %s\n") % serial; @@ -211,15 +209,10 @@ static void store_results( cal_data << boost::format("DATA STARTS HERE\n"); cal_data << "lo_frequency, correction_real, correction_imag, measured, delta\n"; - for (size_t i = 0; i < results.size(); i++) - { - cal_data - << results[i].freq << ", " - << results[i].real_corr << ", " - << results[i].imag_corr << ", " - << results[i].best << ", " - << results[i].delta << "\n" - ; + for (size_t i = 0; i < results.size(); i++) { + cal_data << results[i].freq << ", " << results[i].real_corr << ", " + << results[i].imag_corr << ", " << results[i].best << ", " + << results[i].delta << "\n"; } std::cout << "wrote cal data to " << cal_data_path << std::endl; @@ -228,10 +221,9 @@ static void store_results( /*********************************************************************** * Data capture routine **********************************************************************/ -static void capture_samples( - uhd::usrp::multi_usrp::sptr usrp, +static void capture_samples(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, - std::vector<samp_type > &buff, + std::vector<samp_type>& buff, const size_t nsamps_requested) { buff.resize(nsamps_requested); @@ -243,34 +235,29 @@ static void capture_samples( std::vector<samp_type> discard_buff(nsamps_to_discard); uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = buff.size() + nsamps_to_discard; + stream_cmd.num_samps = buff.size() + nsamps_to_discard; stream_cmd.stream_now = true; usrp->issue_stream_cmd(stream_cmd); size_t num_rx_samps = 0; // Discard the transient samples. rx_stream->recv(&discard_buff.front(), discard_buff.size(), md); - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - { - throw std::runtime_error(str(boost::format( - "Receiver error: %s" - ) % md.strerror())); + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error( + str(boost::format("Receiver error: %s") % md.strerror())); } // Now capture the data we want num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); - //validate the received data - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - { - throw std::runtime_error(str(boost::format( - "Receiver error: %s" - ) % md.strerror())); + // validate the received data + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error( + str(boost::format("Receiver error: %s") % md.strerror())); } - //we can live if all the data didnt come in - if (num_rx_samps > buff.size()/2) - { + // we can live if all the data didnt come in + if (num_rx_samps > buff.size() / 2) { buff.resize(num_rx_samps); return; } @@ -281,15 +268,16 @@ static void capture_samples( /*********************************************************************** * Setup function **********************************************************************/ -static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(std::string &args, std::string &subdev, std::string &serial) +static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal( + std::string& args, std::string& subdev, std::string& serial) { std::cout << std::endl; - std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args + << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); // Configure subdev - if (!subdev.empty()) - { + if (!subdev.empty()) { usrp->set_tx_subdev_spec(subdev); usrp->set_rx_subdev_spec(subdev); } @@ -297,16 +285,18 @@ static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(std::string &args, std::st serial = get_serial(usrp, "tx"); std::cout << "Daughterboard serial: " << serial; - //set the antennas to cal - if (not uhd::has(usrp->get_rx_antennas(), "CAL") or not uhd::has(usrp->get_tx_antennas(), "CAL")) - throw std::runtime_error("This board does not have the CAL antenna option, cannot self-calibrate."); + // set the antennas to cal + if (not uhd::has(usrp->get_rx_antennas(), "CAL") + or not uhd::has(usrp->get_tx_antennas(), "CAL")) + throw std::runtime_error( + "This board does not have the CAL antenna option, cannot self-calibrate."); usrp->set_rx_antenna("CAL"); usrp->set_tx_antenna("CAL"); - //fail if daughterboard has no serial + // fail if daughterboard has no serial check_for_empty_serial(usrp); - //set optimum defaults + // set optimum defaults set_optimum_defaults(usrp); return usrp; @@ -315,25 +305,24 @@ static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(std::string &args, std::st /*********************************************************************** * Function to find optimal RX gain setting (for the current frequency) **********************************************************************/ -UHD_INLINE void set_optimal_rx_gain( - uhd::usrp::multi_usrp::sptr usrp, +UHD_INLINE void set_optimal_rx_gain(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, double wave_freq = 0.0) { - const double gain_step = 3.0; + const double gain_step = 3.0; const double gain_compression_threshold = gain_step * 0.5; - const double actual_rx_rate = usrp->get_rx_rate(); - const double actual_tx_freq = usrp->get_tx_freq(); - const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_tone_freq = actual_tx_freq - actual_rx_freq + wave_freq; + const double actual_rx_rate = usrp->get_rx_rate(); + const double actual_tx_freq = usrp->get_tx_freq(); + const double actual_rx_freq = usrp->get_rx_freq(); + const double bb_tone_freq = actual_tx_freq - actual_rx_freq + wave_freq; const size_t nsamps = size_t(actual_rx_rate / default_fft_bin_size); std::vector<samp_type> buff(nsamps); uhd::gain_range_t rx_gain_range = usrp->get_rx_gain_range(); - double rx_gain = rx_gain_range.start() + gain_step; - double curr_dbrms = 0.0; - double prev_dbrms = 0.0; - double delta = 0.0; + double rx_gain = rx_gain_range.start() + gain_step; + double curr_dbrms = 0.0; + double prev_dbrms = 0.0; + double delta = 0.0; // No sense in setting the gain where this is no gain range if (rx_gain_range.stop() - rx_gain_range.start() < gain_step) @@ -349,20 +338,19 @@ UHD_INLINE void set_optimal_rx_gain( // Initialize prev_dbrms value usrp->set_rx_gain(rx_gain); capture_samples(usrp, rx_stream, buff, nsamps); - prev_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); + prev_dbrms = compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); rx_gain += gain_step; // Find RX gain where signal begins to clip - while (rx_gain <= rx_gain_range.stop()) - { + while (rx_gain <= rx_gain_range.stop()) { usrp->set_rx_gain(rx_gain); capture_samples(usrp, rx_stream, buff, nsamps); - curr_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); - delta = curr_dbrms - prev_dbrms; + curr_dbrms = compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); + delta = curr_dbrms - prev_dbrms; // check if the gain is compressed beyone the threshold if (delta < gain_step - gain_compression_threshold) - break; // if so, we are done + break; // if so, we are done prev_dbrms = curr_dbrms; rx_gain += gain_step; @@ -391,14 +379,14 @@ bool has_tx_error(uhd::tx_streamer::sptr tx_stream) return false; } - return async_md.event_code & (0 - // Any of these errors are considered a problematic TX error: - | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW - | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR - | uhd::async_metadata_t::EVENT_CODE_TIME_ERROR - | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET - | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST - ); + return async_md.event_code + & (0 + // Any of these errors are considered a problematic TX error: + | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW + | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR + | uhd::async_metadata_t::EVENT_CODE_TIME_ERROR + | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET + | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST); } void wait_for_lo_lock(uhd::usrp::multi_usrp::sptr usrp) @@ -407,10 +395,9 @@ void wait_for_lo_lock(uhd::usrp::multi_usrp::sptr usrp) const auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(100); while (not usrp->get_tx_sensor("lo_locked").to_bool() - or not usrp->get_rx_sensor("lo_locked").to_bool()) { + or not usrp->get_rx_sensor("lo_locked").to_bool()) { if (std::chrono::steady_clock::now() > timeout) { - throw std::runtime_error( - "timed out waiting for TX and/or RX LO to lock"); + throw std::runtime_error("timed out waiting for TX and/or RX LO to lock"); } } } diff --git a/host/utils/usrp_e3x0_network_mode.cpp b/host/utils/usrp_e3x0_network_mode.cpp index ac4f47e4d..fbc8aeb28 100644 --- a/host/utils/usrp_e3x0_network_mode.cpp +++ b/host/utils/usrp_e3x0_network_mode.cpp @@ -8,13 +8,10 @@ #include "../lib/usrp/e300/e300_network.hpp" #include <uhd/device.hpp> #include <uhd/exception.hpp> - #include <uhd/transport/if_addrs.hpp> - -#include <boost/program_options.hpp> -#include <boost/format.hpp> #include <boost/asio.hpp> - +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> namespace po = boost::program_options; @@ -25,13 +22,13 @@ static void check_network_ok(void) using namespace boost::asio::ip; std::vector<if_addrs_t> addrs = get_if_addrs(); - if(addrs.size() == 1 and addrs.at(0).inet == address_v4::loopback().to_string()) + if (addrs.size() == 1 and addrs.at(0).inet == address_v4::loopback().to_string()) throw uhd::runtime_error( "No network address except for loopback found.\n" "Make sure your DHCP server is working or configure a static IP"); } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { po::options_description desc("Allowed options"); // clang-format off @@ -45,25 +42,29 @@ int main(int argc, char *argv[]) po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("UHD E3x0 Network Mode %s") % desc << std::endl; return EXIT_FAILURE; } uhd::device_addr_t args; - if(vm.count("fpga")) { + if (vm.count("fpga")) { args["fpga"] = vm["fpga"].as<std::string>(); } try { check_network_ok(); - uhd::usrp::e300::network_server::sptr server = uhd::usrp::e300::network_server::make(args); + uhd::usrp::e300::network_server::sptr server = + uhd::usrp::e300::network_server::make(args); server->run(); - } catch (uhd::assertion_error &e) { - std::cout << "This executable is supposed to run on the device, not on the host." << std::endl - << "Please refer to the manual section on operating your e3x0 device in network mode." << std::endl; + } catch (uhd::assertion_error& e) { + std::cout << "This executable is supposed to run on the device, not on the host." + << std::endl + << "Please refer to the manual section on operating your e3x0 device " + "in network mode." + << std::endl; return EXIT_FAILURE; - } catch (uhd::runtime_error &e) { + } catch (uhd::runtime_error& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; } |