aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/UHDDevice.cpp
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-04-05 20:42:41 -0400
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2013-06-24 01:46:34 +0400
commitd1bcab2731827cdf5020b56063bfe53e2159a99b (patch)
treea50956f931ea8087055bf6e8cb741ccaf615342d /Transceiver52M/UHDDevice.cpp
parent00493f1a413a743c27ff2bb11c041e63a0f0d4ce (diff)
Transceiver52M: Add device offset correction table
Previously, two timing correction values were used for UHD devices depending on the sample rate of 270.833e3 or 400e3 for native GSM or resampled device rate respectively. The correction values compensate for residual timing effects due to analog component delays, filters lag times, and general fudge factors. These values are device specific and over-generalized by the two value configuration. This patch adds the following struct to store these correction values by device type and sample rate - through samples-per-symbol. struct uhd_dev_offset { enum uhd_dev_type type; int sps; double offset; }; Signed-off-by: Thomas Tsou <tom@tsou.cc>
Diffstat (limited to 'Transceiver52M/UHDDevice.cpp')
-rw-r--r--Transceiver52M/UHDDevice.cpp85
1 files changed, 60 insertions, 25 deletions
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index 5874edc..87ef200 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -35,6 +35,8 @@
#define NUM_TX_CHANS 2
#define TX_CHAN_OFFSET 2e6
#define B100_CLK_RT 52e6
+#define TX_AMPL 0.3;
+#define SAMPLE_BUF_SZ (1 << 20)
enum uhd_dev_type {
USRP1,
@@ -43,28 +45,53 @@ enum uhd_dev_type {
NUM_USRP_TYPES,
};
+struct uhd_dev_offset {
+ enum uhd_dev_type type;
+ int sps;
+ double offset;
+};
+
/*
- master_clk_rt - Master clock frequency - ignored if host resampling is
- enabled
+ * Tx / Rx sample offset values. In a perfect world, there is no group delay
+ * though analog components, and behaviour through digital filters exactly
+ * matches calculated values. In reality, there are unaccounted factors,
+ * which are captured in these empirically measured (using a loopback test)
+ * timing correction values.
+ *
+ * Notes:
+ * USRP1 with timestamps is not supported by UHD.
+ */
+static struct uhd_dev_offset uhd_offsets[NUM_USRP_TYPES * 3] = {
+ { USRP1, 1, 0.0 },
+ { USRP1, 2, 0.0 },
+ { USRP1, 4, 0.0 },
+ { USRP2, 1, 5.4394e-5 },
+ { USRP2, 2, 0.0 },
+ { USRP2, 4, 0.0 },
+ { B100, 1, 9.4778e-5 },
+ { B100, 2, 5.1100e-5 },
+ { B100, 4, 2.9418e-5 },
+};
- rx_smpl_offset - Timing correction in seconds between receive and
- transmit timestamps. This value corrects for delays on
- on the RF side of the timestamping point of the device.
- This value is generally empirically measured.
+static double get_dev_offset(enum uhd_dev_type type, int sps)
+{
+ if (type == USRP1) {
+ LOG(ERR) << "Invalid device type";
+ return 0.0;
+ }
- smpl_buf_sz - The receive sample buffer size in bytes.
+ switch (sps) {
+ case 1:
+ return uhd_offsets[3 * type + 0].offset;
+ case 2:
+ return uhd_offsets[3 * type + 1].offset;
+ case 4:
+ return uhd_offsets[3 * type + 2].offset;
+ }
- tx_ampl - Transmit amplitude must be between 0 and 1.0
-*/
-const double master_clk_rt = 13e6;
-const size_t smpl_buf_sz = (1 << 20);
-const float tx_ampl = .3;
-
-#ifdef RESAMPLE
-const double rx_smpl_offset = .00005;
-#else
-const double rx_smpl_offset = 9.4457e-5;
-#endif
+ LOG(ERR) << "Unsupported samples-per-symbols: " << sps;
+ return 0.0;
+}
static TIMESTAMP init_rd_ts = 0;
@@ -158,7 +185,7 @@ private:
*/
class uhd_device : public RadioDevice {
public:
- uhd_device(double rate, bool skip_rx);
+ uhd_device(double rate, int sps, bool skip_rx);
~uhd_device();
bool open(const std::string &args);
@@ -182,7 +209,7 @@ public:
inline TIMESTAMP initialWriteTimestamp() { return init_rd_ts; }
inline TIMESTAMP initialReadTimestamp() { return init_rd_ts; }
- inline double fullScaleInputValue() { return 32000 * tx_ampl; }
+ inline double fullScaleInputValue() { return 32000 * TX_AMPL; }
inline double fullScaleOutputValue() { return 32000; }
double setRxGain(double db);
@@ -223,6 +250,7 @@ private:
enum TxWindowType tx_window;
enum uhd_dev_type dev_type;
+ int sps;
double desired_smpl_rt, actual_smpl_rt;
double tx_gain, tx_gain_min, tx_gain_max;
@@ -286,7 +314,7 @@ void uhd_msg_handler(uhd::msg::type_t type, const std::string &msg)
}
}
-uhd_device::uhd_device(double rate, bool skip_rx)
+uhd_device::uhd_device(double rate, int sps, bool skip_rx)
: desired_smpl_rt(rate), actual_smpl_rt(0),
tx_gain(0.0), tx_gain_min(0.0), tx_gain_max(0.0),
rx_gain(0.0), rx_gain_min(0.0), rx_gain_max(0.0),
@@ -294,6 +322,7 @@ uhd_device::uhd_device(double rate, bool skip_rx)
started(false), aligned(false), rx_pkt_cnt(0), drop_cnt(0),
prev_ts(0,0), ts_offset(0), rx_smpl_buf(NULL)
{
+ this->sps = sps;
this->skip_rx = skip_rx;
}
@@ -511,11 +540,17 @@ bool uhd_device::open(const std::string &args)
return false;
// Create receive buffer
- size_t buf_len = smpl_buf_sz / sizeof(uint32_t);
+ size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t);
rx_smpl_buf = new smpl_buf(buf_len, actual_smpl_rt);
// Set receive chain sample offset
- ts_offset = (TIMESTAMP)(rx_smpl_offset * actual_smpl_rt);
+ double offset = get_dev_offset(dev_type, sps);
+ if (offset == 0.0) {
+ LOG(ERR) << "Unsupported configuration, no correction applied";
+ ts_offset = 0;
+ } else {
+ ts_offset = (TIMESTAMP) (offset * actual_smpl_rt);
+ }
// Initialize and shadow gain values
init_gains();
@@ -1043,7 +1078,7 @@ std::string smpl_buf::str_code(ssize_t code)
}
}
-RadioDevice *RadioDevice::make(double smpl_rt, bool skip_rx)
+RadioDevice *RadioDevice::make(double smpl_rt, int sps, bool skip_rx)
{
- return new uhd_device(smpl_rt, skip_rx);
+ return new uhd_device(smpl_rt, sps, skip_rx);
}