aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-04-05 20:42:41 -0400
committerThomas Tsou <tom@tsou.cc>2013-10-18 13:03:41 -0400
commite3e88149487c72bd722f83865bca571134caa454 (patch)
tree0feebfe01b8eca0e82b731d51db957f7efe7a47e
parent02d88d13808135f35b1cac7a44260e09affbb428 (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>
-rw-r--r--Transceiver52M/UHDDevice.cpp87
-rw-r--r--Transceiver52M/USRPping.cpp2
-rw-r--r--Transceiver52M/radioDevice.h2
-rw-r--r--Transceiver52M/runTransceiver.cpp2
4 files changed, 64 insertions, 29 deletions
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index c194c79..a2b616c 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -32,7 +32,9 @@
#include "config.h"
#endif
-#define B100_CLK_RT 52e6
+#define B100_CLK_RT 52e6
+#define TX_AMPL 0.3
+#define SAMPLE_BUF_SZ (1 << 20)
enum uhd_dev_type {
USRP1,
@@ -41,28 +43,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 = 52e6;
-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 = .0000869;
-#endif
+ LOG(ERR) << "Unsupported samples-per-symbols: " << sps;
+ return 0.0;
+}
/** Timestamp conversion
@param timestamp a UHD or OpenBTS timestamp
@@ -154,7 +181,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);
@@ -178,7 +205,7 @@ public:
inline TIMESTAMP initialWriteTimestamp() { return 0; }
inline TIMESTAMP initialReadTimestamp() { return 0; }
- inline double fullScaleInputValue() { return 32000 * tx_ampl; }
+ inline double fullScaleInputValue() { return 32000 * TX_AMPL; }
inline double fullScaleOutputValue() { return 32000; }
double setRxGain(double db);
@@ -215,6 +242,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;
@@ -278,7 +306,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),
@@ -286,6 +314,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;
}
@@ -474,11 +503,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();
@@ -987,7 +1022,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);
}
diff --git a/Transceiver52M/USRPping.cpp b/Transceiver52M/USRPping.cpp
index 9c09e2a..0ac5565 100644
--- a/Transceiver52M/USRPping.cpp
+++ b/Transceiver52M/USRPping.cpp
@@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
else gLogInit("DEBUG");
//if (argc>2) gSetLogFile(argv[2]);
- RadioDevice *usrp = RadioDevice::make(52.0e6/192.0);
+ RadioDevice *usrp = RadioDevice::make(52.0e6/192.0, 1);
usrp->open("");
diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h
index e5cdde8..ff3421c 100644
--- a/Transceiver52M/radioDevice.h
+++ b/Transceiver52M/radioDevice.h
@@ -31,7 +31,7 @@ class RadioDevice {
/* Available transport bus types */
enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED };
- static RadioDevice *make(double desiredSampleRate, bool skipRx = false);
+ static RadioDevice *make(double desiredSampleRate, int sps, bool skipRx = false);
/** Initialize the USRP */
virtual bool open(const std::string &args)=0;
diff --git a/Transceiver52M/runTransceiver.cpp b/Transceiver52M/runTransceiver.cpp
index 33ab434..ce2724d 100644
--- a/Transceiver52M/runTransceiver.cpp
+++ b/Transceiver52M/runTransceiver.cpp
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
srandom(time(NULL));
int mOversamplingRate = numARFCN/2 + numARFCN;
- RadioDevice *usrp = RadioDevice::make(DEVICERATE * SAMPSPERSYM);
+ RadioDevice *usrp = RadioDevice::make(DEVICERATE * SAMPSPERSYM, SAMPSPERSYM);
if (!usrp->open(deviceArgs)) {
LOG(ALERT) << "Transceiver exiting..." << std::endl;
return EXIT_FAILURE;