<p>rauf.gyulaliev@fairwaves.co has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-trx/+/15685">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add XTRX support<br><br>Change-Id: I1067dfef53aa2669cc7c189cccae10074c674390<br>---<br>M Transceiver52M/Makefile.am<br>M Transceiver52M/device/Makefile.am<br>A Transceiver52M/device/xtrx/Makefile.am<br>A Transceiver52M/device/xtrx/XTRXDevice.cpp<br>A Transceiver52M/device/xtrx/XTRXDevice.h<br>M configure.ac<br>M contrib/systemd/Makefile.am<br>A contrib/systemd/osmo-trx-xtrx.service<br>M debian/control<br>A debian/osmo-trx-xtrx.install<br>M doc/examples/Makefile.am<br>A doc/examples/osmo-trx-xtrx/osmo-trx-xtrx.cfg<br>12 files changed, 735 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/85/15685/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/Transceiver52M/Makefile.am b/Transceiver52M/Makefile.am</span><br><span>index ade4e30..2f636f4 100644</span><br><span>--- a/Transceiver52M/Makefile.am</span><br><span>+++ b/Transceiver52M/Makefile.am</span><br><span>@@ -104,3 +104,13 @@</span><br><span>     $(LMS_LIBS)</span><br><span> osmo_trx_lms_CPPFLAGS  = $(AM_CPPFLAGS) $(LMS_CFLAGS)</span><br><span> endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if DEVICE_XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+bin_PROGRAMS += osmo-trx-xtrx</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_trx_xtrx_SOURCES = osmo-trx.cpp</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_trx_xtrx_LDADD = \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(builddir)/device/xtrx/libdevice.la \</span><br><span style="color: hsl(120, 100%, 40%);">+        $(COMMON_LDADD) \</span><br><span style="color: hsl(120, 100%, 40%);">+     $(XTRX_LIBS)</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_trx_xtrx_CPPFLAGS  = $(AM_CPPFLAGS) $(XTRX_CFLAGS)</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span>diff --git a/Transceiver52M/device/Makefile.am b/Transceiver52M/device/Makefile.am</span><br><span>index 369e877..8460a96 100644</span><br><span>--- a/Transceiver52M/device/Makefile.am</span><br><span>+++ b/Transceiver52M/device/Makefile.am</span><br><span>@@ -13,3 +13,7 @@</span><br><span> if DEVICE_LMS</span><br><span> SUBDIRS += lms</span><br><span> endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if DEVICE_XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+SUBDIRS += xtrx</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span>diff --git a/Transceiver52M/device/xtrx/Makefile.am b/Transceiver52M/device/xtrx/Makefile.am</span><br><span>new file mode 100644</span><br><span>index 0000000..2b99b39</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/xtrx/Makefile.am</span><br><span>@@ -0,0 +1,10 @@</span><br><span style="color: hsl(120, 100%, 40%);">+include $(top_srcdir)/Makefile.common</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/../common</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+noinst_HEADERS = XTRXDevice.h</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+noinst_LTLIBRARIES = libdevice.la</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+libdevice_la_SOURCES = XTRXDevice.cpp</span><br><span>diff --git a/Transceiver52M/device/xtrx/XTRXDevice.cpp b/Transceiver52M/device/xtrx/XTRXDevice.cpp</span><br><span>new file mode 100644</span><br><span>index 0000000..27192bb</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/xtrx/XTRXDevice.cpp</span><br><span>@@ -0,0 +1,455 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* Copyright 2018 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co></span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+        This program is free software: you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+  it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+   the Free Software Foundation, either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+     (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+       but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+      along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "Threads.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "XTRXDevice.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <Logger.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef HAVE_CONFIG_H</span><br><span style="color: hsl(120, 100%, 40%);">+#include "config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+using namespace std;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const double defaultRXBandwidth = 0.5e6;</span><br><span style="color: hsl(120, 100%, 40%);">+const double defaultTXBandwidth = 1.5e6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int time_tx_corr = 60; //20+20+20+20+20;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+XTRXDevice::XTRXDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chans, double lo_offset,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      const std::vector<std::string>& tx_paths,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           const std::vector<std::string>& rx_paths) :</span><br><span style="color: hsl(120, 100%, 40%);">+      RadioDevice(tx_sps, rx_sps, iface, chans, lo_offset, tx_paths, rx_paths)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   LOG(INFO) << "creating XTRX device:"</span><br><span style="color: hsl(120, 100%, 40%);">+                    << " RXSPS: " << rx_sps</span><br><span style="color: hsl(120, 100%, 40%);">+                         << " TXSPS: " << tx_sps</span><br><span style="color: hsl(120, 100%, 40%);">+                         << " chans: " << chans</span><br><span style="color: hsl(120, 100%, 40%);">+                          << " lo_off: " << lo_offset</span><br><span style="color: hsl(120, 100%, 40%);">+                     << " rx_path(0): " << (rx_paths.size() ? rx_paths[0] : "<>")</span><br><span style="color: hsl(120, 100%, 40%);">+                    << " tx_path(0): " << (tx_paths.size() ? tx_paths[0] : "<>");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       txsps = tx_sps;</span><br><span style="color: hsl(120, 100%, 40%);">+       rxsps = rx_sps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rxGain = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   txGain = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ loopback = false;</span><br><span style="color: hsl(120, 100%, 40%);">+     device = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int parse_config(const char* line, const char* argument, int default_value)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    const char* arg_found = strstr(line, argument);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!arg_found)</span><br><span style="color: hsl(120, 100%, 40%);">+               return default_value;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       const char* qe_pos = strchr(arg_found, '=');</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!qe_pos)</span><br><span style="color: hsl(120, 100%, 40%);">+          return default_value;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       int res = strtol(qe_pos + 1, NULL, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (res == 0 && errno) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return default_value;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int XTRXDevice::open(const std::string &args, int ref, bool swap_channels)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   LOG(INFO) << "opening XTRX device '"  << args << "'..";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       int loglevel = parse_config(args.c_str(), "loglevel", 3);</span><br><span style="color: hsl(120, 100%, 40%);">+   int lb_param = parse_config(args.c_str(), "loopback", 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   time_tx_corr = parse_config(args.c_str(), "tcorr", time_tx_corr);</span><br><span style="color: hsl(120, 100%, 40%);">+   int fref     = parse_config(args.c_str(), "refclk", 26000000);</span><br><span style="color: hsl(120, 100%, 40%);">+      int rxdec    = parse_config(args.c_str(), "rxdec", 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    char xtrx_name[500];</span><br><span style="color: hsl(120, 100%, 40%);">+  const char* lend = strchr(args.c_str(), ',');</span><br><span style="color: hsl(120, 100%, 40%);">+ int len = (lend) ? (lend - args.c_str()) : sizeof(xtrx_name) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     strncpy(xtrx_name, args.c_str(), len);</span><br><span style="color: hsl(120, 100%, 40%);">+        xtrx_name[len] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((txsps % 2) || (rxsps % 2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "XTRX TxSPS/RxSPS must be even!";</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (lb_param) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOG(ALERT) << "XTRX LOOPBACK mode is set!";</span><br><span style="color: hsl(120, 100%, 40%);">+           loopback = true;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   int res = xtrx_open(xtrx_name, loglevel, &device);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ALERT) << "XTRX creating failed, device " << xtrx_name << " code " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     double actualMasterClock = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (fref > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            xtrx_set_ref_clk(device, fref, XTRX_CLKSRC_INT);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   res = xtrx_set_samplerate(device,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                       GSMRATE * (double) std::min(txsps, rxsps)  * 32 * 4 * ((rxdec) ? 2 : 1),</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      GSMRATE * (double) rxsps,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     GSMRATE * (double) txsps,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     (rxdec) ? XTRX_SAMPLERATE_FORCE_RX_DECIM : 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         &actualMasterClock,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                       &actualRXSampleRate,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      &actualTXSampleRate);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ALERT) << "XTRX failed to set samplerate RX: " << GSMRATE * (double) rxsps</span><br><span style="color: hsl(120, 100%, 40%);">+                             << " TX: " << GSMRATE * (double) txsps</span><br><span style="color: hsl(120, 100%, 40%);">+                                  << " res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+          return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(INFO) << "XTRX set samplerate Master: " << actualMasterClock</span><br><span style="color: hsl(120, 100%, 40%);">+                                  << " RX: " << actualRXSampleRate</span><br><span style="color: hsl(120, 100%, 40%);">+                                << " TX: " << actualTXSampleRate;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   double bw;</span><br><span style="color: hsl(120, 100%, 40%);">+    double actualbw;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    actualbw = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ bw = defaultRXBandwidth;</span><br><span style="color: hsl(120, 100%, 40%);">+      res = xtrx_tune_rx_bandwidth(device, XTRX_CH_AB, bw, &actualbw);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ALERT) << "XTRX failed to set RX bandwidth: " << bw</span><br><span style="color: hsl(120, 100%, 40%);">+                            << " res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(INFO) << "XTRX set RX bandwidth: " << actualbw;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   actualbw = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ bw = defaultTXBandwidth;</span><br><span style="color: hsl(120, 100%, 40%);">+      res = xtrx_tune_tx_bandwidth(device, XTRX_CH_AB, bw, &actualbw);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ALERT) << "XTRX failed to set TX bandwidth: " << bw</span><br><span style="color: hsl(120, 100%, 40%);">+                            << " res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(INFO) << "XTRX set TX bandwidth: " << actualbw;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   samplesRead = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      samplesWritten = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   started = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return NORMAL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+XTRXDevice::~XTRXDevice()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (device) {</span><br><span style="color: hsl(120, 100%, 40%);">+         xtrx_close(device);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::start() </span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  LOG(INFO) << "starting XTRX...";</span><br><span style="color: hsl(120, 100%, 40%);">+      if (started) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   dataStart = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        dataEnd = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  timeStart = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        timeEnd = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  timeRx = initialReadTimestamp();</span><br><span style="color: hsl(120, 100%, 40%);">+      timestampOffset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  latestWriteTimestamp = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     lastPktTimestamp = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ hi32Timestamp = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    isAligned = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  xtrx_stop(device, XTRX_TX);</span><br><span style="color: hsl(120, 100%, 40%);">+   xtrx_stop(device, XTRX_RX);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ xtrx_set_antenna(device, XTRX_TX_AUTO);</span><br><span style="color: hsl(120, 100%, 40%);">+       xtrx_set_antenna(device, XTRX_RX_AUTO);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     xtrx_run_params_t params;</span><br><span style="color: hsl(120, 100%, 40%);">+     params.dir = XTRX_TRX;</span><br><span style="color: hsl(120, 100%, 40%);">+        params.nflags = (loopback) ? XTRX_RUN_DIGLOOPBACK : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      params.rx.chs = XTRX_CH_AB;</span><br><span style="color: hsl(120, 100%, 40%);">+   params.rx.flags = XTRX_RSP_SISO_MODE;</span><br><span style="color: hsl(120, 100%, 40%);">+ params.rx.hfmt = XTRX_IQ_INT16;</span><br><span style="color: hsl(120, 100%, 40%);">+       params.rx.wfmt = XTRX_WF_16;</span><br><span style="color: hsl(120, 100%, 40%);">+  params.rx.paketsize = 625 * rxsps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  params.tx.chs = XTRX_CH_AB;</span><br><span style="color: hsl(120, 100%, 40%);">+   params.tx.flags = XTRX_RSP_SISO_MODE;</span><br><span style="color: hsl(120, 100%, 40%);">+ params.tx.hfmt = XTRX_IQ_INT16;</span><br><span style="color: hsl(120, 100%, 40%);">+       params.tx.wfmt = XTRX_WF_16;</span><br><span style="color: hsl(120, 100%, 40%);">+  params.tx.paketsize = 625 * txsps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (loopback) {</span><br><span style="color: hsl(120, 100%, 40%);">+               params.tx.flags |= XTRX_RSP_SWAP_AB | XTRX_RSP_SWAP_IQ;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   params.tx_repeat_buf = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  params.rx_stream_start = initialReadTimestamp();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    int res = xtrx_run_ex(device, &params);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ALERT) << "XTRX start failed res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(INFO) << "XTRX started";</span><br><span style="color: hsl(120, 100%, 40%);">+          started = true;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     return started;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::stop() </span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (started) {</span><br><span style="color: hsl(120, 100%, 40%);">+                int res = xtrx_stop(device, XTRX_TRX);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOG(ALERT) << "XTRX stop failed res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+          } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOG(INFO) << "XTRX stopped";</span><br><span style="color: hsl(120, 100%, 40%);">+                  started = false;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return !started;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+TIMESTAMP XTRXDevice::initialWriteTimestamp()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (/*(iface == MULTI_ARFCN) || */(rxsps == txsps))</span><br><span style="color: hsl(120, 100%, 40%);">+           return initialReadTimestamp();</span><br><span style="color: hsl(120, 100%, 40%);">+        else</span><br><span style="color: hsl(120, 100%, 40%);">+          return initialReadTimestamp() * txsps;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double XTRXDevice::maxTxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return 30;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double XTRXDevice::minTxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double XTRXDevice::maxRxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return 30;</span><br><span style="color: hsl(120, 100%, 40%);">+} </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double XTRXDevice::minRxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double XTRXDevice::setTxGain(double dB, size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(ALERT) << "Invalid channel " << chan;</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0.0;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     LOG(NOTICE) << "Setting TX gain to " << dB << " dB.";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = xtrx_set_gain(device, XTRX_CH_AB, XTRX_TX_PAD_GAIN, dB - 30, &txGain);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ERR) << "Error setting TX gain res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(NOTICE) << "Actual TX gain: " << txGain << " dB.";</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return txGain;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double XTRXDevice::setRxGain(double dB, size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(ALERT) << "Invalid channel " << chan;</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0.0;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     LOG(NOTICE) << "Setting RX gain to " << dB << " dB.";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = xtrx_set_gain(device, XTRX_CH_AB, XTRX_RX_LNA_GAIN, dB, &rxGain);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ERR) << "Error setting RX gain res: " << res;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(NOTICE) << "Actual RX gain: " << rxGain << " dB.";</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return rxGain;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+// NOTE: Assumes sequential reads</span><br><span style="color: hsl(120, 100%, 40%);">+int XTRXDevice::readSamples(std::vector<short *> &bufs, int len, bool *overrun,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     TIMESTAMP timestamp, bool *underrun, unsigned *RSSI)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!started)</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  struct xtrx_recv_ex_info ri;</span><br><span style="color: hsl(120, 100%, 40%);">+  ri.samples = len;</span><br><span style="color: hsl(120, 100%, 40%);">+     ri.buffer_count = bufs.size();</span><br><span style="color: hsl(120, 100%, 40%);">+        ri.buffers = (void* const*)&bufs[0];</span><br><span style="color: hsl(120, 100%, 40%);">+      ri.flags = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       int res = xtrx_recv_sync_ex(device, &ri);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG(ALERT) << "xtrx_recv_sync failed res " << res << " current TS " << timeRx << " req TS" << timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     timeRx += len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      // TODO get rid of it!</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < len * 2; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+              bufs[0][i] <<= 4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (underrun) {</span><br><span style="color: hsl(120, 100%, 40%);">+               *underrun = (ri.out_events & RCVEX_EVENT_FILLED_ZERO);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     return len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int XTRXDevice::writeSamples(std::vector<short *> &bufs, int len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        bool *underrun, unsigned long long timestamp,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         bool isControl)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!started)</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   xtrx_send_ex_info_t nfo;</span><br><span style="color: hsl(120, 100%, 40%);">+      nfo.buffers = (const void* const*)&bufs[0];</span><br><span style="color: hsl(120, 100%, 40%);">+       nfo.buffer_count = bufs.size();</span><br><span style="color: hsl(120, 100%, 40%);">+       nfo.flags = XTRX_TX_DONT_BUFFER;</span><br><span style="color: hsl(120, 100%, 40%);">+      nfo.samples = len;</span><br><span style="color: hsl(120, 100%, 40%);">+    nfo.ts = timestamp - time_tx_corr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  int res = xtrx_send_sync_ex(device, &nfo);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (res != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOG(ALERT) << "xtrx_send_sync_ex returned " << res << " len=" << len << " ts=" << timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (*underrun) {</span><br><span style="color: hsl(120, 100%, 40%);">+              *underrun = (nfo.out_flags & XTRX_TX_DISCARDED_TO);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return len;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::setRxAntenna(const std::string & ant, size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  LOG(ALERT) << "CH" << chan << ": RX ANTENNA: " << ant.c_str();</span><br><span style="color: hsl(120, 100%, 40%);">+    return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+std::string XTRXDevice::getRxAntenna(size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return "";</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::setTxAntenna(const std::string & ant, size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(ALERT) << "CH" << chan << ": TX ANTENNA: " << ant.c_str();</span><br><span style="color: hsl(120, 100%, 40%);">+    return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+std::string XTRXDevice::getTxAntenna(size_t chan )</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return "";</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::requiresRadioAlign()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+GSM::Time XTRXDevice::minLatency()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return GSM::Time(6,7);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::updateAlignment(TIMESTAMP timestamp) </span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        LOG(ALERT) << "Update Aligment " << timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+  return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::setTxFreq(double wFreq, size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int res;</span><br><span style="color: hsl(120, 100%, 40%);">+      double actual = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(ALERT) << "Invalid channel " << chan;</span><br><span style="color: hsl(120, 100%, 40%);">+               return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((res = xtrx_tune(device, XTRX_TUNE_TX_FDD, wFreq, &actual)) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(INFO) << "set RX: " << wFreq << std::endl</span><br><span style="color: hsl(120, 100%, 40%);">+                               << "    actual freq: " << actual << std::endl;</span><br><span style="color: hsl(120, 100%, 40%);">+          return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     else {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOG(ALERT) << "set RX: " << wFreq << "failed (code: " << res << ")" << std::endl;</span><br><span style="color: hsl(120, 100%, 40%);">+           return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool XTRXDevice::setRxFreq(double wFreq, size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int res;</span><br><span style="color: hsl(120, 100%, 40%);">+      double actual = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(ALERT) << "Invalid channel " << chan;</span><br><span style="color: hsl(120, 100%, 40%);">+               return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((res = xtrx_tune(device, XTRX_TUNE_RX_FDD, wFreq, &actual)) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(INFO) << "set RX: " << wFreq << std::endl</span><br><span style="color: hsl(120, 100%, 40%);">+                               << "    actual freq: " << actual << std::endl;</span><br><span style="color: hsl(120, 100%, 40%);">+          return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     else {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOG(ALERT) << "set RX: " << wFreq << "failed (code: " << res << ")" << std::endl;</span><br><span style="color: hsl(120, 100%, 40%);">+           return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     InterfaceType iface, size_t chans, double lo_offset,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          const std::vector < std::string > &tx_paths,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        const std::vector < std::string > &rx_paths)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return new XTRXDevice(tx_sps, rx_sps, iface, chans, lo_offset, tx_paths, rx_paths);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/Transceiver52M/device/xtrx/XTRXDevice.h b/Transceiver52M/device/xtrx/XTRXDevice.h</span><br><span>new file mode 100644</span><br><span>index 0000000..d4810e4</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/xtrx/XTRXDevice.h</span><br><span>@@ -0,0 +1,180 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef _XTRX_DEVICE_H_</span><br><span style="color: hsl(120, 100%, 40%);">+#define _XTRX_DEVICE_H_</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef HAVE_CONFIG_H</span><br><span style="color: hsl(120, 100%, 40%);">+#include "config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "radioDevice.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/time.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string></span><br><span style="color: hsl(120, 100%, 40%);">+#include <iostream></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "Threads.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include <xtrx_api.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class XTRXDevice: public RadioDevice {</span><br><span style="color: hsl(120, 100%, 40%);">+private:</span><br><span style="color: hsl(120, 100%, 40%);">+   int txsps;</span><br><span style="color: hsl(120, 100%, 40%);">+    int rxsps;</span><br><span style="color: hsl(120, 100%, 40%);">+    double actualTXSampleRate;      ///< the actual XTRX sampling rate</span><br><span style="color: hsl(120, 100%, 40%);">+ double actualRXSampleRate;      ///< the actual XTRX sampling rate</span><br><span style="color: hsl(120, 100%, 40%);">+ //unsigned int decimRate;       ///< the XTRX decimation rate</span><br><span style="color: hsl(120, 100%, 40%);">+      //unsigned int interRate;       ///< the XTRX decimation rate</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned long long samplesRead; ///< number of samples read from XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned long long samplesWritten;      ///< number of samples sent to XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bool started;                   ///< flag indicates XTRX has started</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     short *data;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned long dataStart;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned long dataEnd;</span><br><span style="color: hsl(120, 100%, 40%);">+        TIMESTAMP timeStart;</span><br><span style="color: hsl(120, 100%, 40%);">+  TIMESTAMP timeEnd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  TIMESTAMP timeRx;</span><br><span style="color: hsl(120, 100%, 40%);">+     bool isAligned;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     Mutex writeLock;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    short *currData;                ///< internal data buffer when reading from XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+   TIMESTAMP currTimestamp;        ///< timestamp of internal data buffer</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned currLen;               ///< size of internal data buffer</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        TIMESTAMP timestampOffset;       ///< timestamp offset b/w Tx and Rx blocks</span><br><span style="color: hsl(120, 100%, 40%);">+        TIMESTAMP latestWriteTimestamp;  ///< timestamp of most recent ping command</span><br><span style="color: hsl(120, 100%, 40%);">+        TIMESTAMP pingTimestamp;           ///< timestamp of most recent ping response</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned long hi32Timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned long lastPktTimestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     double rxGain;</span><br><span style="color: hsl(120, 100%, 40%);">+        double txGain;</span><br><span style="color: hsl(120, 100%, 40%);">+        bool loopback;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      xtrx_dev* device;</span><br><span style="color: hsl(120, 100%, 40%);">+public:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /** Object constructor */</span><br><span style="color: hsl(120, 100%, 40%);">+     XTRXDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chans, double lo_offset,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const std::vector<std::string>& tx_paths,</span><br><span style="color: hsl(120, 100%, 40%);">+                           const std::vector<std::string>& rx_paths);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ~XTRXDevice();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** Instantiate the XTRX */</span><br><span style="color: hsl(120, 100%, 40%);">+   int open(const std::string &args, int ref, bool swap_channels);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /** Start the XTRX */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool start();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /** Stop the XTRX */</span><br><span style="color: hsl(120, 100%, 40%);">+  bool stop();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /** Set priority not supported */</span><br><span style="color: hsl(120, 100%, 40%);">+     void setPriority(float prio = 0.5) { }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      enum TxWindowType getWindowType() { return TX_WINDOW_FIXED; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /**</span><br><span style="color: hsl(120, 100%, 40%);">+   Read samples from the XTRX.</span><br><span style="color: hsl(120, 100%, 40%);">+   @param buf preallocated buf to contain read result</span><br><span style="color: hsl(120, 100%, 40%);">+    @param len number of samples desired</span><br><span style="color: hsl(120, 100%, 40%);">+  @param overrun Set if read buffer has been overrun, e.g. data not being read fast enough</span><br><span style="color: hsl(120, 100%, 40%);">+      @param timestamp The timestamp of the first samples to be read</span><br><span style="color: hsl(120, 100%, 40%);">+        @param underrun Set if XTRX does not have data to transmit, e.g. data not being sent fast enough</span><br><span style="color: hsl(120, 100%, 40%);">+      @param RSSI The received signal strength of the read result</span><br><span style="color: hsl(120, 100%, 40%);">+   @return The number of samples actually read</span><br><span style="color: hsl(120, 100%, 40%);">+   */</span><br><span style="color: hsl(120, 100%, 40%);">+    int readSamples(std::vector<short *> &buf, int len, bool *overrun,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  TIMESTAMP timestamp = 0xffffffff, bool *underrun = NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      unsigned *RSSI = NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+       /**</span><br><span style="color: hsl(120, 100%, 40%);">+           Write samples to the XTRX.</span><br><span style="color: hsl(120, 100%, 40%);">+            @param buf Contains the data to be written.</span><br><span style="color: hsl(120, 100%, 40%);">+           @param len number of samples to write.</span><br><span style="color: hsl(120, 100%, 40%);">+                @param underrun Set if XTRX does not have data to transmit, e.g. data not being sent fast enough</span><br><span style="color: hsl(120, 100%, 40%);">+              @param timestamp The timestamp of the first sample of the data buffer.</span><br><span style="color: hsl(120, 100%, 40%);">+                @param isControl Set if data is a control packet, e.g. a ping command</span><br><span style="color: hsl(120, 100%, 40%);">+         @return The number of samples actually written</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+    int writeSamples(std::vector<short *> &bufs, int len, bool *underrun,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        TIMESTAMP timestamp = 0xffffffff, bool isControl = false);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /** Update the alignment between the read and write timestamps */</span><br><span style="color: hsl(120, 100%, 40%);">+     bool updateAlignment(TIMESTAMP timestamp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /** Set the transmitter frequency */</span><br><span style="color: hsl(120, 100%, 40%);">+  bool setTxFreq(double wFreq, size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** Set the receiver frequency */</span><br><span style="color: hsl(120, 100%, 40%);">+     bool setRxFreq(double wFreq, size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** Returns the starting write Timestamp*/</span><br><span style="color: hsl(120, 100%, 40%);">+    TIMESTAMP initialWriteTimestamp(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** Returns the starting read Timestamp*/</span><br><span style="color: hsl(120, 100%, 40%);">+     TIMESTAMP initialReadTimestamp(void) { return 20000;}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /** returns the full-scale transmit amplitude **/</span><br><span style="color: hsl(120, 100%, 40%);">+     double fullScaleInputValue() {return (double) 32767*0.7;}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /** returns the full-scale receive amplitude **/</span><br><span style="color: hsl(120, 100%, 40%);">+      double fullScaleOutputValue() {return (double) 32767;}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** sets the receive chan gain, returns the gain setting **/</span><br><span style="color: hsl(120, 100%, 40%);">+  double setRxGain(double dB, size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /** get the current receive gain */</span><br><span style="color: hsl(120, 100%, 40%);">+   double getRxGain(size_t chan = 0) { return rxGain; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /** return maximum Rx Gain **/</span><br><span style="color: hsl(120, 100%, 40%);">+        double maxRxGain(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /** return minimum Rx Gain **/</span><br><span style="color: hsl(120, 100%, 40%);">+        double minRxGain(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /** sets the transmit chan gain, returns the gain setting **/</span><br><span style="color: hsl(120, 100%, 40%);">+ double setTxGain(double dB, size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /** gets the current transmit gain **/</span><br><span style="color: hsl(120, 100%, 40%);">+        double getTxGain(size_t chan = 0) { return txGain; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /** return maximum Tx Gain **/</span><br><span style="color: hsl(120, 100%, 40%);">+        double maxTxGain(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /** return minimum Rx Gain **/</span><br><span style="color: hsl(120, 100%, 40%);">+        double minTxGain(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /** sets the RX path to use, returns true if successful and false otherwise */</span><br><span style="color: hsl(120, 100%, 40%);">+        bool setRxAntenna(const std::string & ant, size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /** return the used RX path */</span><br><span style="color: hsl(120, 100%, 40%);">+        std::string getRxAntenna(size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /** sets the RX path to use, returns true if successful and false otherwise */</span><br><span style="color: hsl(120, 100%, 40%);">+        bool setTxAntenna(const std::string & ant, size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /** return the used RX path */</span><br><span style="color: hsl(120, 100%, 40%);">+        std::string getTxAntenna(size_t chan = 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /** return whether user drives synchronization of Tx/Rx of USRP */</span><br><span style="color: hsl(120, 100%, 40%);">+    bool requiresRadioAlign();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /** return whether user drives synchronization of Tx/Rx of USRP */</span><br><span style="color: hsl(120, 100%, 40%);">+    virtual GSM::Time minLatency();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /** Return internal status values */</span><br><span style="color: hsl(120, 100%, 40%);">+  inline double getTxFreq(size_t chan = 0) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+        inline double getRxFreq(size_t chan = 0) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+        inline double getSampleRate() { return actualTXSampleRate; }</span><br><span style="color: hsl(120, 100%, 40%);">+  inline double numberRead() { return samplesRead; }</span><br><span style="color: hsl(120, 100%, 40%);">+    inline double numberWritten() { return samplesWritten; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif // _XTRX_DEVICE_H_</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/configure.ac b/configure.ac</span><br><span>index 350c77c..c0e49b6 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -125,6 +125,11 @@</span><br><span>         [enable LimeSuite based transceiver])</span><br><span> ])</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AC_ARG_WITH(xtrx, [</span><br><span style="color: hsl(120, 100%, 40%);">+    AS_HELP_STRING([--with-xtrx],</span><br><span style="color: hsl(120, 100%, 40%);">+        [enable XTRX based transceiver])</span><br><span style="color: hsl(120, 100%, 40%);">+])</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AC_ARG_WITH(singledb, [</span><br><span>     AS_HELP_STRING([--with-singledb],</span><br><span>         [enable single daughterboard use on USRP1])</span><br><span>@@ -164,6 +169,10 @@</span><br><span>     PKG_CHECK_MODULES(LMS, LimeSuite)</span><br><span> ])</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AS_IF([test "x$with_xtrx" = "xyes"], [</span><br><span style="color: hsl(120, 100%, 40%);">+    PKG_CHECK_MODULES(XTRX, libxtrx)</span><br><span style="color: hsl(120, 100%, 40%);">+])</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AS_IF([test "x$with_uhd" != "xno"],[</span><br><span>     PKG_CHECK_MODULES(UHD, uhd >= 003.011,</span><br><span>         [AC_DEFINE(USE_UHD_3_11, 1, UHD version 3.11.0 or higher)],</span><br><span>@@ -226,6 +235,7 @@</span><br><span> AM_CONDITIONAL(DEVICE_UHD, [test "x$with_uhd" != "xno"])</span><br><span> AM_CONDITIONAL(DEVICE_USRP1, [test "x$with_usrp1" = "xyes"])</span><br><span> AM_CONDITIONAL(DEVICE_LMS, [test "x$with_lms" = "xyes"])</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CONDITIONAL(DEVICE_XTRX, [test "x$with_xtrx" = "xyes"])</span><br><span> AM_CONDITIONAL(ARCH_ARM, [test "x$with_neon" = "xyes" || test "x$with_neon_vfpv4" = "xyes"])</span><br><span> AM_CONDITIONAL(ARCH_ARM_A15, [test "x$with_neon_vfpv4" = "xyes"])</span><br><span> </span><br><span>@@ -310,6 +320,7 @@</span><br><span>     Transceiver52M/device/uhd/Makefile \</span><br><span>     Transceiver52M/device/usrp1/Makefile \</span><br><span>     Transceiver52M/device/lms/Makefile \</span><br><span style="color: hsl(120, 100%, 40%);">+    Transceiver52M/device/xtrx/Makefile \</span><br><span>     tests/Makefile \</span><br><span>     tests/CommonLibs/Makefile \</span><br><span>     tests/Transceiver52M/Makefile \</span><br><span>diff --git a/contrib/systemd/Makefile.am b/contrib/systemd/Makefile.am</span><br><span>index 800b1e1..28db86a 100644</span><br><span>--- a/contrib/systemd/Makefile.am</span><br><span>+++ b/contrib/systemd/Makefile.am</span><br><span>@@ -18,5 +18,10 @@</span><br><span> SYSTEMD_SERVICES += osmo-trx-lms.service</span><br><span> endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+if DEVICE_XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+SYSTEMD_SERVICES += osmo-trx-xtrx.service</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+EXTRA_DIST = $(SYSTEMD_SERVICES)</span><br><span> systemdsystemunit_DATA = $(SYSTEMD_SERVICES)</span><br><span> endif # HAVE_SYSTEMD</span><br><span>diff --git a/contrib/systemd/osmo-trx-xtrx.service b/contrib/systemd/osmo-trx-xtrx.service</span><br><span>new file mode 100644</span><br><span>index 0000000..c131812</span><br><span>--- /dev/null</span><br><span>+++ b/contrib/systemd/osmo-trx-xtrx.service</span><br><span>@@ -0,0 +1,11 @@</span><br><span style="color: hsl(120, 100%, 40%);">+[Unit]</span><br><span style="color: hsl(120, 100%, 40%);">+Description=Osmocom SDR BTS L1 Transceiver (XTRX backend)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+[Service]</span><br><span style="color: hsl(120, 100%, 40%);">+Type=simple</span><br><span style="color: hsl(120, 100%, 40%);">+Restart=always</span><br><span style="color: hsl(120, 100%, 40%);">+ExecStart=/usr/bin/osmo-trx-xtrx -C /etc/osmocom/osmo-trx-xtrx.cfg</span><br><span style="color: hsl(120, 100%, 40%);">+RestartSec=2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+[Install]</span><br><span style="color: hsl(120, 100%, 40%);">+WantedBy=multi-user.target</span><br><span>diff --git a/debian/control b/debian/control</span><br><span>index 750f7b9..109704a 100644</span><br><span>--- a/debian/control</span><br><span>+++ b/debian/control</span><br><span>@@ -91,6 +91,25 @@</span><br><span>  between different telecommunication associations for developing new</span><br><span>  generations of mobile phone networks. (post-2G/GSM)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+Package: osmo-trx-xtrx</span><br><span style="color: hsl(120, 100%, 40%);">+Architecture: any</span><br><span style="color: hsl(120, 100%, 40%);">+Depends: ${shlibs:Depends}, ${misc:Depends}</span><br><span style="color: hsl(120, 100%, 40%);">+Description: SDR transceiver that implements Layer 1 of a GSM BTS (XTRX)</span><br><span style="color: hsl(120, 100%, 40%);">+ OsmoTRX is a software-defined radio transceiver that implements the Layer 1</span><br><span style="color: hsl(120, 100%, 40%);">+ physical layer of a BTS comprising the following 3GPP specifications:</span><br><span style="color: hsl(120, 100%, 40%);">+ .</span><br><span style="color: hsl(120, 100%, 40%);">+ TS 05.01 "Physical layer on the radio path"</span><br><span style="color: hsl(120, 100%, 40%);">+ TS 05.02 "Multiplexing and Multiple Access on the Radio Path"</span><br><span style="color: hsl(120, 100%, 40%);">+ TS 05.04 "Modulation"</span><br><span style="color: hsl(120, 100%, 40%);">+ TS 05.10 "Radio subsystem synchronization"</span><br><span style="color: hsl(120, 100%, 40%);">+ .</span><br><span style="color: hsl(120, 100%, 40%);">+ In this context, BTS is "Base transceiver station". It's the stations that</span><br><span style="color: hsl(120, 100%, 40%);">+ connect mobile phones to the mobile network.</span><br><span style="color: hsl(120, 100%, 40%);">+ .</span><br><span style="color: hsl(120, 100%, 40%);">+ 3GPP is the "3rd Generation Partnership Project" which is the collaboration</span><br><span style="color: hsl(120, 100%, 40%);">+ between different telecommunication associations for developing new</span><br><span style="color: hsl(120, 100%, 40%);">+ generations of mobile phone networks. (post-2G/GSM)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> Package: osmo-trx-doc</span><br><span> Architecture: all</span><br><span> Section: doc</span><br><span>diff --git a/debian/osmo-trx-xtrx.install b/debian/osmo-trx-xtrx.install</span><br><span>new file mode 100644</span><br><span>index 0000000..8601346</span><br><span>--- /dev/null</span><br><span>+++ b/debian/osmo-trx-xtrx.install</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+etc/osmocom/osmo-trx-xtrx.cfg</span><br><span style="color: hsl(120, 100%, 40%);">+lib/systemd/system/osmo-trx-xtrx.service</span><br><span style="color: hsl(120, 100%, 40%);">+/usr/bin/osmo-trx-xtrx</span><br><span style="color: hsl(120, 100%, 40%);">+/usr/share/doc/osmo-trx/examples/osmo-trx-xtrx/osmo-trx-xtrx.cfg /usr/share/doc/osmo-trx/examples/osmo-trx-xtrx/</span><br><span>diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am</span><br><span>index 88d9142..4b52834 100644</span><br><span>--- a/doc/examples/Makefile.am</span><br><span>+++ b/doc/examples/Makefile.am</span><br><span>@@ -14,6 +14,10 @@</span><br><span> OSMOCONF_FILES += osmo-trx-lms/osmo-trx-lms.cfg</span><br><span> endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+if DEVICE_XTRX</span><br><span style="color: hsl(120, 100%, 40%);">+OSMOCONF_FILES += osmo-trx-xtrx/osmo-trx-xtrx.cfg</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> osmoconf_DATA = $(OSMOCONF_FILES)</span><br><span> EXTRA_DIST = $(OSMOCONF_FILES)</span><br><span> </span><br><span>diff --git a/doc/examples/osmo-trx-xtrx/osmo-trx-xtrx.cfg b/doc/examples/osmo-trx-xtrx/osmo-trx-xtrx.cfg</span><br><span>new file mode 100644</span><br><span>index 0000000..e2c67d6</span><br><span>--- /dev/null</span><br><span>+++ b/doc/examples/osmo-trx-xtrx/osmo-trx-xtrx.cfg</span><br><span>@@ -0,0 +1,22 @@</span><br><span style="color: hsl(120, 100%, 40%);">+log stderr</span><br><span style="color: hsl(120, 100%, 40%);">+ logging filter all 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging color 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging print category 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging timestamp 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging print file basename</span><br><span style="color: hsl(120, 100%, 40%);">+ logging level set-all info</span><br><span style="color: hsl(120, 100%, 40%);">+!</span><br><span style="color: hsl(120, 100%, 40%);">+line vty</span><br><span style="color: hsl(120, 100%, 40%);">+ no login</span><br><span style="color: hsl(120, 100%, 40%);">+!</span><br><span style="color: hsl(120, 100%, 40%);">+trx</span><br><span style="color: hsl(120, 100%, 40%);">+ bind-ip 127.0.0.1</span><br><span style="color: hsl(120, 100%, 40%);">+ remote-ip 127.0.0.1</span><br><span style="color: hsl(120, 100%, 40%);">+ base-port 5700</span><br><span style="color: hsl(120, 100%, 40%);">+ egprs disable</span><br><span style="color: hsl(120, 100%, 40%);">+ tx-sps 4</span><br><span style="color: hsl(120, 100%, 40%);">+ rx-sps 4</span><br><span style="color: hsl(120, 100%, 40%);">+ rt-prio 18</span><br><span style="color: hsl(120, 100%, 40%);">+ chan 0</span><br><span style="color: hsl(120, 100%, 40%);">+  tx-path BAND1</span><br><span style="color: hsl(120, 100%, 40%);">+  rx-path LNAW</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-trx/+/15685">change 15685</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-trx/+/15685"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1067dfef53aa2669cc7c189cccae10074c674390 </div>
<div style="display:none"> Gerrit-Change-Number: 15685 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: rauf.gyulaliev@fairwaves.co </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>