diff options
author | Thomas Tsou <tom@tsou.cc> | 2013-10-11 13:49:55 -0400 |
---|---|---|
committer | Thomas Tsou <tom@tsou.cc> | 2013-10-18 13:10:17 -0400 |
commit | c1f7c42a33a1125f8b39f53a1b6e1bae38376857 (patch) | |
tree | fd79543a262281b4cbf04bfb09f305b95a715dd4 /Transceiver52M/UHDDevice.cpp | |
parent | 2c282f5e1268146761413a145fd8ae2fb523fa4f (diff) |
Transceiver52M: Setup dual sample rate transceiver
This patch applies oversampling, when selected with 4 sps,
to the downlink only, while running the receiver with
minimal sampling at 1 sps. These split sample rates allow
us to run a highly accurate downlink signal with minimal
distortion, while keeping receive path channel filtering
on the FPGA.
Without this patch, we oversample the receive path and
require a steep receive filter to get similar adjacent
channel suppression as the FPGA halfband / CIC filter
combination, which comes with a high computational cost.
Signed-off-by: Thomas Tsou <tom@tsou.cc>
Diffstat (limited to 'Transceiver52M/UHDDevice.cpp')
-rw-r--r-- | Transceiver52M/UHDDevice.cpp | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp index 2bd767c..ad821de 100644 --- a/Transceiver52M/UHDDevice.cpp +++ b/Transceiver52M/UHDDevice.cpp @@ -66,14 +66,14 @@ struct uhd_dev_offset { static struct uhd_dev_offset uhd_offsets[NUM_USRP_TYPES * 2] = { { USRP1, 1, 0.0 }, { USRP1, 4, 0.0 }, - { USRP2, 1, 5.4394e-5 }, - { USRP2, 4, 0.0 }, - { B100, 1, 9.4778e-5 }, - { B100, 4, 2.9418e-5 }, - { B200, 1, 0.0 }, - { B200, 4, 9.8358e-5 }, - { UMTRX, 1, 9.4778e-5 }, - { UMTRX, 4, 0.0 }, + { USRP2, 1, 1.1815e-4 }, + { USRP2, 4, 7.7538e-5 }, + { B100, 1, 9.9692e-5 }, + { B100, 4, 6.5545e-5 }, + { B200, 1, 9.6000e-5 }, + { B200, 4, 6.4615e-5 }, + { UMTRX, 1, 9.9692e-5 }, + { UMTRX, 4, 7.3846e-5 }, }; static double get_dev_offset(enum uhd_dev_type type, int sps) @@ -248,7 +248,7 @@ public: double getTxFreq() { return tx_freq; } double getRxFreq() { return rx_freq; } - inline double getSampleRate() { return actual_smpl_rt; } + inline double getSampleRate() { return tx_rate; } inline double numberRead() { return rx_pkt_cnt; } inline double numberWritten() { return 0; } @@ -271,7 +271,7 @@ private: enum uhd_dev_type dev_type; int sps; - double desired_smpl_rt, actual_smpl_rt; + double tx_rate, rx_rate; double tx_gain, tx_gain_min, tx_gain_max; double rx_gain, rx_gain_min, rx_gain_max; @@ -293,7 +293,7 @@ private: void init_gains(); void set_ref_clk(bool ext_clk); int set_master_clk(double rate); - int set_rates(double rate); + int set_rates(double tx_rate, double rx_rate); bool parse_dev_type(); bool flush_recv(size_t num_pkts); int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls); @@ -407,7 +407,7 @@ int uhd_device::set_master_clk(double clk_rate) return 0; } -int uhd_device::set_rates(double rate) +int uhd_device::set_rates(double tx_rate, double rx_rate) { double offset_limit = 1.0; double tx_offset, rx_offset; @@ -420,21 +420,22 @@ int uhd_device::set_rates(double rate) // Set sample rates try { - usrp_dev->set_tx_rate(rate); - usrp_dev->set_rx_rate(rate); + usrp_dev->set_tx_rate(tx_rate); + usrp_dev->set_rx_rate(rx_rate); } catch (const std::exception &ex) { - LOG(ALERT) << "UHD rate setting failed: " << rate; + LOG(ALERT) << "UHD rate setting failed"; LOG(ALERT) << ex.what(); return -1; } - actual_smpl_rt = usrp_dev->get_tx_rate(); + this->tx_rate = usrp_dev->get_tx_rate(); + this->rx_rate = usrp_dev->get_rx_rate(); - tx_offset = fabs(usrp_dev->get_tx_rate() - rate); - rx_offset = fabs(usrp_dev->get_rx_rate() - rate); + tx_offset = fabs(this->tx_rate - tx_rate); + rx_offset = fabs(this->rx_rate - rx_rate); if ((tx_offset > offset_limit) || (rx_offset > offset_limit)) { LOG(ALERT) << "Actual sample rate differs from desired rate"; - LOG(ALERT) << "Tx/Rx (" << usrp_dev->get_rx_rate() << "/" - << usrp_dev->get_rx_rate() << ")"; + LOG(ALERT) << "Tx/Rx (" << this->tx_rate << "/" + << this->rx_rate << ")"; return -1; } @@ -552,13 +553,14 @@ int uhd_device::open(const std::string &args) rx_spp = rx_stream->get_max_num_samps(); // Set rates - desired_smpl_rt = select_rate(dev_type, sps); - if ((desired_smpl_rt > 0.0) && (set_rates(desired_smpl_rt) < 0)) + double _tx_rate = select_rate(dev_type, sps); + double _rx_rate = _tx_rate / sps; + if ((_tx_rate > 0.0) && (set_rates(_tx_rate, _rx_rate) < 0)) return -1; // Create receive buffer size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t); - rx_smpl_buf = new smpl_buf(buf_len, actual_smpl_rt); + rx_smpl_buf = new smpl_buf(buf_len, rx_rate); // Set receive chain sample offset double offset = get_dev_offset(dev_type, sps); @@ -566,7 +568,7 @@ int uhd_device::open(const std::string &args) LOG(ERR) << "Unsupported configuration, no correction applied"; ts_offset = 0; } else { - ts_offset = (TIMESTAMP) (offset * actual_smpl_rt); + ts_offset = (TIMESTAMP) (offset * rx_rate); } // Initialize and shadow gain values @@ -719,7 +721,7 @@ int uhd_device::readSamples(short *buf, int len, bool *overrun, // Shift read time with respect to transmit clock timestamp += ts_offset; - ts = convert_time(timestamp, actual_smpl_rt); + ts = convert_time(timestamp, rx_rate); LOG(DEBUG) << "Requested timestamp = " << ts.get_real_secs(); // Check that timestamp is valid @@ -788,7 +790,7 @@ int uhd_device::writeSamples(short *buf, int len, bool *underrun, metadata.has_time_spec = true; metadata.start_of_burst = false; metadata.end_of_burst = false; - metadata.time_spec = convert_time(timestamp, actual_smpl_rt); + metadata.time_spec = convert_time(timestamp, tx_rate); // No control packets if (isControl) { |