From 88e02e0d55f7a80180402c7c86132d22a43ec551 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 11 Nov 2011 16:06:50 -0800 Subject: uhd: created rx IQ imbalance app to parallel tx --- host/lib/usrp/common/apply_corrections.cpp | 106 +++++++++++++++++++---------- host/lib/usrp/common/apply_corrections.hpp | 6 ++ host/lib/usrp/usrp2/usrp2_impl.cpp | 13 +++- host/lib/usrp/usrp2/usrp2_impl.hpp | 3 +- 4 files changed, 89 insertions(+), 39 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/common/apply_corrections.cpp b/host/lib/usrp/common/apply_corrections.cpp index 6929696bb..c3ac4256a 100644 --- a/host/lib/usrp/common/apply_corrections.cpp +++ b/host/lib/usrp/common/apply_corrections.cpp @@ -30,33 +30,40 @@ namespace fs = boost::filesystem; -struct tx_fe_cal_t{ - double tx_lo_freq; +boost::mutex corrections_mutex; + +/*********************************************************************** + * Helper routines + **********************************************************************/ +static double linear_interp(double x, double x0, double y0, double x1, double y1){ + return y0 + (x - x0)*(y1 - y0)/(x1 - x0); +} + +/*********************************************************************** + * FE apply corrections implementation + **********************************************************************/ +struct fe_cal_t{ + double lo_freq; double iq_corr_real; double iq_corr_imag; }; -static bool tx_fe_cal_comp(tx_fe_cal_t a, tx_fe_cal_t b){ - return (a.tx_lo_freq < b.tx_lo_freq); +static bool fe_cal_comp(fe_cal_t a, fe_cal_t b){ + return (a.lo_freq < b.lo_freq); } -boost::mutex corrections_mutex;; -static uhd::dict > cache; +static uhd::dict > fe_cal_cache; -static double linear_interp(double x, double x0, double y0, double x1, double y1){ - return y0 + (x - x0)*(y1 - y0)/(x1 - x0); -} - -static std::complex get_tx_fe_iq_correction( - const std::string &key, const double tx_lo_freq +static std::complex get_fe_iq_correction( + const std::string &key, const double lo_freq ){ - const std::vector &datas = cache[key]; + const std::vector &datas = fe_cal_cache[key]; //search for lo freq size_t lo_index = 0; size_t hi_index = datas.size()-1; for (size_t i = 0; i < datas.size(); i++){ - if (datas[i].tx_lo_freq > tx_lo_freq){ + if (datas[i].lo_freq > lo_freq){ hi_index = i; break; } @@ -68,34 +75,32 @@ static std::complex get_tx_fe_iq_correction( //interpolation time return std::complex( - linear_interp(tx_lo_freq, datas[lo_index].tx_lo_freq, datas[lo_index].iq_corr_real, datas[hi_index].tx_lo_freq, datas[hi_index].iq_corr_real), - linear_interp(tx_lo_freq, datas[lo_index].tx_lo_freq, datas[lo_index].iq_corr_imag, datas[hi_index].tx_lo_freq, datas[hi_index].iq_corr_imag) + linear_interp(lo_freq, datas[lo_index].lo_freq, datas[lo_index].iq_corr_real, datas[hi_index].lo_freq, datas[hi_index].iq_corr_real), + linear_interp(lo_freq, datas[lo_index].lo_freq, datas[lo_index].iq_corr_imag, datas[hi_index].lo_freq, datas[hi_index].iq_corr_imag) ); } -static void _apply_tx_fe_corrections( - uhd::property_tree::sptr sub_tree, //starts at mboards/x - const std::string &slot, //name of dboard slot - const double tx_lo_freq //actual lo freq +static void apply_fe_corrections( + uhd::property_tree::sptr sub_tree, + const uhd::fs_path &db_path, + const uhd::fs_path &fe_path, + const std::string &file_prefix, + const double lo_freq ){ - //path constants - const uhd::fs_path tx_db_path = "dboards/" + slot + "/tx_eeprom"; - const uhd::fs_path tx_fe_path = "tx_frontends/" + slot + "/iq_balance/value"; - //extract eeprom serial - const uhd::usrp::dboard_eeprom_t db_eeprom = sub_tree->access(tx_db_path).get(); + const uhd::usrp::dboard_eeprom_t db_eeprom = sub_tree->access(db_path).get(); //make the calibration file path - const fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd" / "cal" / ("tx_fe_cal_v0.1_" + db_eeprom.serial + ".csv"); + const fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd" / "cal" / (file_prefix + db_eeprom.serial + ".csv"); if (not fs::exists(cal_data_path)) return; //parse csv file or get from cache - if (not cache.has_key(cal_data_path.string())){ + if (not fe_cal_cache.has_key(cal_data_path.string())){ std::ifstream cal_data(cal_data_path.string().c_str()); const uhd::csv::rows_type rows = uhd::csv::to_rows(cal_data); bool read_data = false, skip_next = false;; - std::vector datas; + std::vector datas; BOOST_FOREACH(const uhd::csv::row_type &row, rows){ if (not read_data and not row.empty() and row[0] == "DATA STARTS HERE"){ read_data = true; @@ -107,32 +112,61 @@ static void _apply_tx_fe_corrections( skip_next = false; continue; } - tx_fe_cal_t data; - std::sscanf(row[0].c_str(), "%lf" , &data.tx_lo_freq); + fe_cal_t data; + std::sscanf(row[0].c_str(), "%lf" , &data.lo_freq); std::sscanf(row[1].c_str(), "%lf" , &data.iq_corr_real); std::sscanf(row[2].c_str(), "%lf" , &data.iq_corr_imag); datas.push_back(data); } - std::sort(datas.begin(), datas.end(), tx_fe_cal_comp); - cache[cal_data_path.string()] = datas; + std::sort(datas.begin(), datas.end(), fe_cal_comp); + fe_cal_cache[cal_data_path.string()] = datas; UHD_MSG(status) << "Loaded " << cal_data_path.string() << std::endl; } - sub_tree->access >(tx_fe_path) - .set(get_tx_fe_iq_correction(cal_data_path.string(), tx_lo_freq)); + sub_tree->access >(fe_path) + .set(get_fe_iq_correction(cal_data_path.string(), lo_freq)); } +/*********************************************************************** + * Wrapper routines with nice try/catch + print + **********************************************************************/ void uhd::usrp::apply_tx_fe_corrections( property_tree::sptr sub_tree, //starts at mboards/x const std::string &slot, //name of dboard slot - const double tx_lo_freq //actual lo freq + const double lo_freq //actual lo freq ){ boost::mutex::scoped_lock l(corrections_mutex); try{ - _apply_tx_fe_corrections(sub_tree, slot, tx_lo_freq); + apply_fe_corrections( + sub_tree, + "dboards/" + slot + "/tx_eeprom", + "tx_frontends/" + slot + "/iq_balance/value", + "tx_fe_cal_v0.1_", + lo_freq + ); } catch(const std::exception &e){ UHD_MSG(error) << "Failure in apply_tx_fe_corrections: " << e.what() << std::endl; } } + +void uhd::usrp::apply_rx_fe_corrections( + property_tree::sptr sub_tree, //starts at mboards/x + const std::string &slot, //name of dboard slot + const double lo_freq //actual lo freq +){ + boost::mutex::scoped_lock l(corrections_mutex); + try{ + apply_fe_corrections( + sub_tree, + "dboards/" + slot + "/rx_eeprom", + "rx_frontends/" + slot + "/iq_balance/value", + "rx_fe_cal_v0.1_", + lo_freq + ); + } + catch(const std::exception &e){ + UHD_MSG(error) << "Failure in apply_rx_fe_corrections: " << e.what() << std::endl; + } +} diff --git a/host/lib/usrp/common/apply_corrections.hpp b/host/lib/usrp/common/apply_corrections.hpp index 8aabab636..c516862d1 100644 --- a/host/lib/usrp/common/apply_corrections.hpp +++ b/host/lib/usrp/common/apply_corrections.hpp @@ -30,6 +30,12 @@ namespace uhd{ namespace usrp{ const double tx_lo_freq //actual lo freq ); + void apply_rx_fe_corrections( + property_tree::sptr sub_tree, //starts at mboards/x + const std::string &slot, //name of dboard slot + const double rx_lo_freq //actual lo freq + ); + }} //namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 6170948ca..14fa93221 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -608,6 +608,11 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){ _tree->access(db_tx_fe_path / name / "freq" / "value") .subscribe(boost::bind(&usrp2_impl::set_tx_fe_corrections, this, mb, _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(db_rx_fe_path / name / "freq" / "value") + .subscribe(boost::bind(&usrp2_impl::set_rx_fe_corrections, this, mb, _1)); + } } //initialize io handling @@ -661,8 +666,12 @@ sensor_value_t usrp2_impl::get_ref_locked(const std::string &mb){ return sensor_value_t("Ref", lock, "locked", "unlocked"); } -void usrp2_impl::set_tx_fe_corrections(const std::string &mb, const double tx_lo_freq){ - apply_tx_fe_corrections(this->get_tree()->subtree("/mboards/" + mb), "A", tx_lo_freq); +void usrp2_impl::set_rx_fe_corrections(const std::string &mb, const double lo_freq){ + apply_rx_fe_corrections(this->get_tree()->subtree("/mboards/" + mb), "A", lo_freq); +} + +void usrp2_impl::set_tx_fe_corrections(const std::string &mb, const double lo_freq){ + apply_tx_fe_corrections(this->get_tree()->subtree("/mboards/" + mb), "A", lo_freq); } #include diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 74ef3d460..278dc713e 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -106,7 +106,8 @@ private: uhd::sensor_value_t get_mimo_locked(const std::string &); uhd::sensor_value_t get_ref_locked(const std::string &); - void set_tx_fe_corrections(const std::string &mb, const double tx_lo_freq); + void set_rx_fe_corrections(const std::string &mb, const double); + void set_tx_fe_corrections(const std::string &mb, const double); //device properties interface uhd::property_tree::sptr get_tree(void) const{ -- cgit v1.2.3