aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-11-16 06:39:31 +0000
committerJosh Blum <josh@joshknows.com>2011-11-16 06:39:31 +0000
commit95568c8b30490f630a72b665b135c46549ee5882 (patch)
tree35d00a6ad0c7cc4fe1a8c2ea4e89b8e47e9e694a
parent075e6a9788856d6951df42349afef7816852ca68 (diff)
downloaduhd-95568c8b30490f630a72b665b135c46549ee5882.tar.gz
uhd-95568c8b30490f630a72b665b135c46549ee5882.tar.bz2
uhd-95568c8b30490f630a72b665b135c46549ee5882.zip
e100: added self-cal support with minor speedups
-rw-r--r--host/lib/usrp/e100/e100_impl.cpp21
-rw-r--r--host/lib/usrp/e100/e100_impl.hpp2
-rw-r--r--host/utils/uhd_cal_rx_iq_balance.cpp2
-rw-r--r--host/utils/uhd_cal_tx_dc_offset.cpp5
-rw-r--r--host/utils/uhd_cal_tx_iq_balance.cpp5
-rw-r--r--host/utils/usrp_cal_utils.hpp36
6 files changed, 52 insertions, 19 deletions
diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp
index 7804f7fd8..8b7756461 100644
--- a/host/lib/usrp/e100/e100_impl.cpp
+++ b/host/lib/usrp/e100/e100_impl.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include "apply_corrections.hpp"
#include "e100_impl.hpp"
#include "e100_regs.hpp"
#include <uhd/utils/msg.hpp>
@@ -374,6 +375,18 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){
_dboard_iface, _tree->subtree(mb_path / "dboards/A")
);
+ //bind frontend corrections to the dboard freq props
+ const fs_path db_tx_fe_path = mb_path / "dboards" / "A" / "tx_frontends";
+ BOOST_FOREACH(const std::string &name, _tree->list(db_tx_fe_path)){
+ _tree->access<double>(db_tx_fe_path / name / "freq" / "value")
+ .subscribe(boost::bind(&e100_impl::set_tx_fe_corrections, this, _1));
+ }
+ const fs_path db_rx_fe_path = mb_path / "dboards" / "A" / "rx_frontends";
+ BOOST_FOREACH(const std::string &name, _tree->list(db_rx_fe_path)){
+ _tree->access<double>(db_rx_fe_path / name / "freq" / "value")
+ .subscribe(boost::bind(&e100_impl::set_rx_fe_corrections, this, _1));
+ }
+
//initialize io handling
this->io_init();
@@ -450,3 +463,11 @@ void e100_impl::check_fpga_compat(void){
}
_tree->create<std::string>("/mboards/0/fpga_version").set(str(boost::format("%u.%u") % fpga_major % fpga_minor));
}
+
+void e100_impl::set_rx_fe_corrections(const double lo_freq){
+ apply_rx_fe_corrections(this->get_tree()->subtree("/mboards/0"), "A", lo_freq);
+}
+
+void e100_impl::set_tx_fe_corrections(const double lo_freq){
+ apply_tx_fe_corrections(this->get_tree()->subtree("/mboards/0"), "A", lo_freq);
+}
diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp
index f3e481b93..2ea890375 100644
--- a/host/lib/usrp/e100/e100_impl.hpp
+++ b/host/lib/usrp/e100/e100_impl.hpp
@@ -130,6 +130,8 @@ private:
void update_clock_source(const std::string &);
uhd::sensor_value_t get_ref_locked(void);
void check_fpga_compat(void);
+ void set_rx_fe_corrections(const double);
+ void set_tx_fe_corrections(const double);
};
diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp
index ee6b28abc..da9ccbdb3 100644
--- a/host/utils/uhd_cal_rx_iq_balance.cpp
+++ b/host/utils/uhd_cal_rx_iq_balance.cpp
@@ -222,7 +222,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
result.delta = best_suppression - initial_suppression;
results.push_back(result);
if (vm.count("verbose")){
- std::cout << boost::format("%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;
}
diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp
index 5ef9f823c..af5b60d14 100644
--- a/host/utils/uhd_cal_tx_dc_offset.cpp
+++ b/host/utils/uhd_cal_tx_dc_offset.cpp
@@ -50,11 +50,12 @@ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, const double tx_wave_fre
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] = float(tx_wave_ampl) * wave_table_lookup(index += step);
+ buff[i] = table(index += step);
}
tx_stream->send(&buff.front(), buff.size(), md);
}
@@ -219,7 +220,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
result.delta = initial_dc_dbrms - lowest_offset;
results.push_back(result);
if (vm.count("verbose")){
- std::cout << boost::format("%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;
}
diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp
index d7851424a..ff965e040 100644
--- a/host/utils/uhd_cal_tx_iq_balance.cpp
+++ b/host/utils/uhd_cal_tx_iq_balance.cpp
@@ -50,11 +50,12 @@ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, const double tx_wave_fre
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] = float(tx_wave_ampl) * wave_table_lookup(index += step);
+ buff[i] = table(index += step);
}
tx_stream->send(&buff.front(), buff.size(), md);
}
@@ -224,7 +225,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
result.delta = best_suppression - initial_suppression;
results.push_back(result);
if (vm.count("verbose")){
- std::cout << boost::format("%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;
}
diff --git a/host/utils/usrp_cal_utils.hpp b/host/utils/usrp_cal_utils.hpp
index 6417b5d8b..0faaf9a84 100644
--- a/host/utils/usrp_cal_utils.hpp
+++ b/host/utils/usrp_cal_utils.hpp
@@ -58,6 +58,10 @@ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp){
usrp->set_tx_rate(4e6);
usrp->set_rx_rate(4e6);
}
+ else if (mb_name.find("E10") != std::string::npos){
+ usrp->set_tx_rate(4e6);
+ usrp->set_rx_rate(8e6);
+ }
else{
throw std::runtime_error("self-calibration is not supported for this hardware");
}
@@ -85,18 +89,22 @@ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp){
/***********************************************************************
* Sinusoid wave table
**********************************************************************/
-static inline std::vector<std::complex<float> > gen_table(void){
- std::vector<std::complex<float> > wave_table(wave_table_len);
- for (size_t i = 0; i < wave_table_len; i++){
- wave_table[i] = std::complex<float>(std::polar(1.0, (tau*i)/wave_table_len));
+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] = std::complex<float>(std::polar(ampl, (tau*i)/wave_table_len));
+ }
}
- return wave_table;
-}
-static inline std::complex<float> wave_table_lookup(const size_t index){
- static const std::vector<std::complex<float> > wave_table = gen_table();
- return wave_table[index % wave_table_len];
-}
+ inline std::complex<float> operator()(const size_t index) const{
+ return _table[index % wave_table_len];
+ }
+
+private:
+ std::vector<std::complex<float> > _table;
+};
/***********************************************************************
* Compute power of a tone
@@ -106,16 +114,16 @@ static inline double compute_tone_dbrms(
const double freq //freq is fractional
){
//shift the samples so the tone at freq is down at DC
- std::vector<std::complex<double> > shifted(samples.size() - skip_initial_samps);
+ std::vector<std::complex<float> > shifted(samples.size() - skip_initial_samps);
for (size_t i = 0; i < shifted.size(); i++){
- shifted[i] = std::complex<double>(samples[i+skip_initial_samps]) * std::polar<double>(1.0, -freq*tau*i);
+ shifted[i] = samples[i+skip_initial_samps] * std::complex<float>(std::polar(1.0, -freq*tau*i));
}
//filter the samples with a narrow low pass
- std::complex<double> iir_output = 0, iir_last = 0;
+ std::complex<float> iir_output = 0, iir_last = 0;
double output = 0;
for (size_t i = 0; i < shifted.size(); i++){
- iir_output = alpha * shifted[i] + (1-alpha)*iir_last;
+ iir_output = float(alpha) * shifted[i] + float(1-alpha)*iir_last;
iir_last = iir_output;
output += std::abs(iir_output);
}