aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils
diff options
context:
space:
mode:
authormichael-west <michael.west@ettus.com>2021-04-15 23:51:25 -0700
committerAaron Rossetto <aaron.rossetto@ni.com>2021-04-29 15:12:05 -0500
commit1488781b091484d52e7c9b96115b0ab5a9b3e957 (patch)
treed34089ad092c8bed572757d9edccd5183fe57549 /host/utils
parentd689df23fb4bf38e1abc23b06767fc26aa27c163 (diff)
downloaduhd-1488781b091484d52e7c9b96115b0ab5a9b3e957.tar.gz
uhd-1488781b091484d52e7c9b96115b0ab5a9b3e957.tar.bz2
uhd-1488781b091484d52e7c9b96115b0ab5a9b3e957.zip
utils: Improve cal TX threads
Increase thread priority on TX thread and remove memory copy to reduce underruns. Signed-off-by: michael-west <michael.west@ettus.com>
Diffstat (limited to 'host/utils')
-rw-r--r--host/utils/uhd_cal_rx_iq_balance.cpp43
-rw-r--r--host/utils/uhd_cal_tx_dc_offset.cpp51
-rw-r--r--host/utils/uhd_cal_tx_iq_balance.cpp50
-rw-r--r--host/utils/usrp_cal_utils.hpp94
4 files changed, 86 insertions, 152 deletions
diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp
index ff074acef..8b9ada1a4 100644
--- a/host/utils/uhd_cal_rx_iq_balance.cpp
+++ b/host/utils/uhd_cal_rx_iq_balance.cpp
@@ -10,11 +10,8 @@
#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/math/special_functions/round.hpp>
#include <boost/program_options.hpp>
-#include <boost/thread/thread.hpp>
#include <chrono>
#include <cmath>
#include <complex>
@@ -22,38 +19,10 @@
#include <ctime>
#include <functional>
#include <iostream>
-#include <thread>
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_ampl)
-{
- // set max TX gain
- usrp->set_tx_gain(usrp->get_tx_gain_range().stop());
-
- // 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);
-
- // 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
- md.end_of_burst = true;
- tx_stream->send("", 0, md);
-}
-
-/***********************************************************************
* Tune RX and TX routine
**********************************************************************/
static double tune_rx_and_tx(
@@ -142,8 +111,10 @@ int UHD_SAFE_MAIN(int argc, char* argv[])
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
// create a transmitter thread
- boost::thread_group threads;
- threads.create_thread(std::bind(&tx_thread, usrp, tx_stream, tx_wave_ampl));
+ std::atomic_flag transmit = ATOMIC_FLAG_INIT;
+ transmit.test_and_set();
+ auto transmitter =
+ std::thread(std::bind(&tx_thread, &transmit, usrp, tx_stream, 0.0, tx_wave_ampl));
// re-usable buffer for samples
std::vector<samp_type> buff;
@@ -292,10 +263,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[])
std::cout << std::endl;
// stop the transmitter
- threads.interrupt_all();
- std::this_thread::sleep_for(
- std::chrono::milliseconds(500)); // wait for threads to finish
- threads.join_all();
+ transmit.clear();
+ transmitter.join();
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 9a0a3bb77..cb97fca29 100644
--- a/host/utils/uhd_cal_tx_dc_offset.cpp
+++ b/host/utils/uhd_cal_tx_dc_offset.cpp
@@ -10,55 +10,17 @@
#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/math/special_functions/round.hpp>
#include <boost/program_options.hpp>
-#include <boost/thread/thread.hpp>
#include <chrono>
#include <complex>
#include <ctime>
#include <functional>
#include <iostream>
-#include <thread>
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)
-{
- // set max TX gain
- usrp->set_tx_gain(usrp->get_tx_gain_range().stop());
-
- // 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);
-
- // 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);
- wave_table table(tx_wave_ampl);
-
- // 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
- md.end_of_burst = true;
- tx_stream->send("", 0, md);
-}
-
-/***********************************************************************
* Tune RX and TX routine
**********************************************************************/
static double tune_rx_and_tx(
@@ -148,9 +110,10 @@ int UHD_SAFE_MAIN(int argc, char* argv[])
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
// create a transmitter thread
- boost::thread_group threads;
- threads.create_thread(
- std::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl));
+ std::atomic_flag transmit = ATOMIC_FLAG_INIT;
+ transmit.test_and_set();
+ auto transmitter = std::thread(
+ std::bind(&tx_thread, &transmit, usrp, tx_stream, tx_wave_freq, tx_wave_ampl));
// re-usable buffer for samples
std::vector<samp_type> buff;
@@ -290,10 +253,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[])
std::cout << std::endl;
// stop the transmitter
- threads.interrupt_all();
- std::this_thread::sleep_for(
- std::chrono::milliseconds(500)); // wait for threads to finish
- threads.join_all();
+ transmit.clear();
+ transmitter.join();
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 5f2695784..5c9f981c9 100644
--- a/host/utils/uhd_cal_tx_iq_balance.cpp
+++ b/host/utils/uhd_cal_tx_iq_balance.cpp
@@ -7,55 +7,18 @@
#include "usrp_cal_utils.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 <chrono>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <iostream>
-#include <thread>
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)
-{
- // set max TX gain
- usrp->set_tx_gain(usrp->get_tx_gain_range().stop());
-
- // 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);
-
- // 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);
- wave_table table(tx_wave_ampl);
-
- // 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
- md.end_of_burst = true;
- tx_stream->send("", 0, md);
-}
-
-/***********************************************************************
* Tune RX and TX routine
**********************************************************************/
static double tune_rx_and_tx(
@@ -145,9 +108,10 @@ int UHD_SAFE_MAIN(int argc, char* argv[])
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
// create a transmitter thread
- boost::thread_group threads;
- threads.create_thread(
- std::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl));
+ std::atomic_flag transmit = ATOMIC_FLAG_INIT;
+ transmit.test_and_set();
+ auto transmitter = std::thread(
+ std::bind(&tx_thread, &transmit, usrp, tx_stream, tx_wave_freq, tx_wave_ampl));
// re-usable buffer for samples
std::vector<samp_type> buff;
@@ -292,10 +256,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[])
std::cout << std::endl;
// stop the transmitter
- threads.interrupt_all();
- std::this_thread::sleep_for(
- std::chrono::milliseconds(500)); // wait for threads to finish
- threads.join_all();
+ transmit.clear();
+ transmitter.join();
store_results(results, "TX", "tx", "iq", serial);
diff --git a/host/utils/usrp_cal_utils.hpp b/host/utils/usrp_cal_utils.hpp
index c0b9b115e..1b9df9d03 100644
--- a/host/utils/usrp_cal_utils.hpp
+++ b/host/utils/usrp_cal_utils.hpp
@@ -11,9 +11,11 @@
#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/algorithm.hpp>
+#include <uhd/utils/math.hpp>
#include <uhd/utils/paths.hpp>
+#include <uhd/utils/thread.hpp>
+#include <atomic>
#include <chrono>
-#include <cmath>
#include <complex>
#include <cstdlib>
#include <fstream>
@@ -31,8 +33,7 @@ typedef std::complex<float> samp_type;
/***********************************************************************
* Constants
**********************************************************************/
-static const double tau = 6.28318531;
-static const size_t wave_table_len = 65536;
+static const double tau = 2 * uhd::math::PI;
static const size_t num_search_steps = 5;
static const double default_precision = 0.0001;
static const double default_freq_step = 7.3e6;
@@ -126,28 +127,6 @@ void check_for_empty_serial(uhd::usrp::multi_usrp::sptr usrp)
}
/***********************************************************************
- * Sinusoid wave table
- **********************************************************************/
-class wave_table
-{
-public:
- wave_table(const double ampl)
- {
- _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));
- }
-
- inline samp_type operator()(const size_t index) const
- {
- return _table[index % wave_table_len];
- }
-
-private:
- std::vector<samp_type> _table;
-};
-
-/***********************************************************************
* Compute power of a tone
**********************************************************************/
static inline double compute_tone_dbrms(const std::vector<samp_type>& samples,
@@ -173,7 +152,6 @@ static inline void write_samples_to_file(
outfile.close();
}
-
/***********************************************************************
* Store data to file
**********************************************************************/
@@ -347,6 +325,70 @@ UHD_INLINE void set_optimal_rx_gain(uhd::usrp::multi_usrp::sptr usrp,
usrp->set_rx_gain(rx_gain);
}
+/***********************************************************************
+ * Transmit thread
+ **********************************************************************/
+static void tx_thread(std::atomic_flag* transmit,
+ uhd::usrp::multi_usrp::sptr usrp,
+ uhd::tx_streamer::sptr tx_stream,
+ const double tx_wave_freq,
+ const double tx_wave_ampl)
+{
+ // increase thread priority for TX to prevent underruns
+ uhd::set_thread_priority();
+
+ // set max TX gain
+ usrp->set_tx_gain(usrp->get_tx_gain_range().stop());
+
+ // setup variables
+ uhd::tx_metadata_t md;
+ md.has_time_spec = false;
+ const double tx_rate = usrp->get_tx_rate();
+ const size_t frame_size = tx_stream->get_max_num_samps();
+
+ // set up buffer
+ // make buffer size of 1 second aligned to a complete wave
+ // to provide accuracy down to 1 Hz with no discontinuity
+ const size_t buff_size =
+ tx_wave_freq == 0.0
+ ? frame_size
+ : static_cast<size_t>(tx_rate)
+ - static_cast<size_t>((tx_wave_freq - static_cast<size_t>(tx_wave_freq))
+ * tx_rate / tx_wave_freq);
+ // Since send calls are aligned to the frame size, make the buffer 1 frame
+ // larger to prevent an overrun when it reaches the end and wraps around.
+ std::vector<samp_type> buff(buff_size + frame_size);
+
+ // fill buffer
+ for (size_t i = 0; i < buff.size(); i++) {
+ if (tx_wave_freq == 0.0) {
+ // fill with constant value
+ buff[i] = samp_type(static_cast<float>(tx_wave_ampl), 0.0);
+ } else {
+ // fill with sine waves
+ buff[i] =
+ samp_type(std::polar(tx_wave_ampl, (tau * i * tx_wave_freq / tx_rate)));
+ }
+ }
+
+ // send until stopped
+ size_t index = 0;
+ while (transmit->test_and_set()) {
+ // send calls are aligned to the frame size for optimal performance
+ tx_stream->send(&buff[index], frame_size, md);
+
+ // increment index
+ index += frame_size;
+
+ // wrap around at end of buffer
+ // (actual buffer size is 1 frame larger to prevent overrun)
+ index %= buff_size;
+ }
+
+ // send a mini EOB packet
+ md.end_of_burst = true;
+ tx_stream->send("", 0, md);
+}
/*! Returns true if any error on the TX stream has occurred
*/