<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9599">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Initial work towards direct LimeSuite support in OsmoTRX<br><br>This is work in progress towards a direct LimeSuite driver in OsmoTRX,<br>bypassing the currently rather complex stack of wrappers by going<br>through UHD, SoapyUHD, SoapySDR and LimeSuite.<br><br>Change-Id: Iaef29c4c2585ef8c2f94866c9591919f538c1a2d<br>---<br>A Transceiver52M/device/lms/LMSDevice.cpp<br>A Transceiver52M/device/lms/LMSDevice.h<br>2 files changed, 648 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/Transceiver52M/device/lms/LMSDevice.cpp b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>new file mode 100644</span><br><span>index 0000000..ed51cdb</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>@@ -0,0 +1,469 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* Copyright 2018 sysmocom - s.f.m.c. GmbH</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%);">+#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 "Logger.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "Threads.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "LMSDevice.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <lime/LimeSuite.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 LMSDevice::masterClockRate = 52.0e6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+LMSDevice::LMSDevice(size_t sps)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   LOG(INFO) << "creating LMS device...";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      m_lms_device = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  this->sps = sps;</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 void lms_log_callback(int lvl, const char *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* map lime specific log levels */</span><br><span style="color: hsl(120, 100%, 40%);">+    static const lvl_map[4] = {</span><br><span style="color: hsl(120, 100%, 40%);">+           [0] = LOGL_FATAL,</span><br><span style="color: hsl(120, 100%, 40%);">+             [1] = LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+             [2] = LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+            [3] = LOGL_INFO,</span><br><span style="color: hsl(120, 100%, 40%);">+              [4] = LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+     };</span><br><span style="color: hsl(120, 100%, 40%);">+    /* protect against future higher log level values (lower importance) */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (lvl >= ARRAY_SIZE(lvl_map))</span><br><span style="color: hsl(120, 100%, 40%);">+            lvl = ARRAY_SIZE(lvl_map)-1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        LOG(lvl) << msg;</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 LMSDevice::open(const std::string &, int, bool)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       lms_info_str dev_str;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t dac_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   LOG(INFO) << "opening LMS device..";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        LMS_RegisterLogHandler(&lms_log_callback);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      rc = LMS_Open(&m_lms_dev, NULL, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rc != 0)</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%);">+  if (LMS_SetSampleRate(m_lms_dev, GSMRATE, sps) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* FIXME: make this device/model dependent, like UHDDevice:dev_param_map! */</span><br><span style="color: hsl(120, 100%, 40%);">+  ts_offset = static_caset<TIMESTAMP>(8.9e-5 * GSMRATE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (ref) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case REF_INTERNAL:</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Ugly API: Selecting clock source implicit by writing to VCTCXO DAC ?!? */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (LMS_VCTCXORead(m_lms_dev, &dac_val) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                   goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             if (LMS_VCTCXOWrite(m_lms_dev, dac_val) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case REF_EXTENAL:</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Assume an external 10 MHz reference clock */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, 10000000.0) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                 goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(ALERT) << "Invalid reference type";</span><br><span style="color: hsl(120, 100%, 40%);">+               goto out_close;</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 (LMS_Init(m_lms_dev) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Perform Rx and Tx calibration */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (LMS_Calibrate(m_lms_dev, LMS_CH_RX, chan, 270000.0, 0) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+            goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (LMS_Calibrate(m_lms_dev, LMS_CH_TX, chan, 270000.0, 0) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+            goto out_close;</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%);">+out_close:</span><br><span style="color: hsl(120, 100%, 40%);">+  LOG(ALERT) << "Error in LMS open, closing: " << LMS_GetLastErrorMessage();</span><br><span style="color: hsl(120, 100%, 40%);">+      LMS_Close(m_lms_dev);</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%);">+bool LMSDevice::start()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   LOG(INFO) << "starting LMS...";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (LMS_EnableChannel(m_lms_dev, LMS_CH_RX, 0, true) < 0)</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%);">+       if (LMS_EnableChannel(m_lms_dev, LMS_CH_TX, 0, true) < 0)</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%);">+       // Set gains to midpoint</span><br><span style="color: hsl(120, 100%, 40%);">+      setTxGain((minTxGain() + maxTxGain()) / 2);</span><br><span style="color: hsl(120, 100%, 40%);">+   setRxGain((minRxGain() + maxRxGain()) / 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .isTx = false,</span><br><span style="color: hsl(120, 100%, 40%);">+                .channel = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+         .fifoSize = 1024 * 1024,</span><br><span style="color: hsl(120, 100%, 40%);">+              .throughputVsLatency = 0.3,</span><br><span style="color: hsl(120, 100%, 40%);">+           .dataFmt = LMS_FMT_I16,</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     m_lms_stream_tx = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .ixTx = true,</span><br><span style="color: hsl(120, 100%, 40%);">+         .channel = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+         .fifoSize = 1024 * 1024,</span><br><span style="color: hsl(120, 100%, 40%);">+              .throughputVsLatency = 0.3,</span><br><span style="color: hsl(120, 100%, 40%);">+           .dataFmt = LMS_FMT_I16,</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 (LMS_SetupStream(m_lms_dev, &m_lms_stream_rx) < 0)</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%);">+       if (LMS_SetupStream(m_lms_dev, &m_lms_stream_tx) < 0)</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%);">+       if (LMS_StartStream(&m_lms_stream_rx) < 0)</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%);">+       if (LMS_StartStream(&m_lms_stream_tx) < 0)</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%);">+       started = true;</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 LMSDevice::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%);">+         return true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        LMS_StopStream(&m_lms_stream_tx);</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_StopStream(&m_lms_stream_rx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       LMS_EnableChannel(m_lms_dev, LMS_CH_RX, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+    LMS_EnableChannel(m_lms_dev, LMS_CH_TX, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+</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%);">+double LMSDevice::maxTxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return 60.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 LMSDevice::minTxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double LMSDevice::maxRxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return 70.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 LMSDevice::minRxGain()</span><br><span style="color: hsl(120, 100%, 40%);">+{</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+double LMSDevice::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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (dB > maxTxGain())</span><br><span style="color: hsl(120, 100%, 40%);">+              dB = maxTxGain();</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dB < minTxGain())</span><br><span style="color: hsl(120, 100%, 40%);">+              dB = minTxGain();</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%);">+ if (LMS_SetGaindB(m_lms_dev, LMS_CH_TX, chan, dB) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ERR) << "Error setting TX gain";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 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%);">+double LMSDevice::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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   dB = 47.0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (dB > maxRxGain())</span><br><span style="color: hsl(120, 100%, 40%);">+              dB = maxRxGain();</span><br><span style="color: hsl(120, 100%, 40%);">+     if (dB < minRxGain())</span><br><span style="color: hsl(120, 100%, 40%);">+              dB = minRxGain();</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%);">+ if (LMS_SetGaindB(m_lms_dev, LMS_CH_RX, chan, dB) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ERR) << "Error setting RX gain";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 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%);">+int get_ant_idx(const char *name, bool dir_tx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    lms_name_t name_list;</span><br><span style="color: hsl(120, 100%, 40%);">+ int num_names;</span><br><span style="color: hsl(120, 100%, 40%);">+        num_names = LMS_GetAntennaList(m_lms_dev, dir_tx, &name_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i < num_names; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!strcmp(name, name_list[i]))</span><br><span style="color: hsl(120, 100%, 40%);">+                      return i;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</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%);">+bool LMSDevice::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%);">+    int idx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (chan >= rx_paths.size()) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Requested non-existent 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%);">+   idx = get_ant_idx(ant, LMS_CH_RX);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (idx < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Invalid Rx Antenna";</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 (LMS_SetAntenna(m_lms_dev, LMS_CH_RX, chan, idx) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOG(ALERT) << "Unable to set Rx Antenna";</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 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 LMSDevice::getRxAntenna(size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (chan >= rx_paths.size()) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Requested non-existent channel " << chan;</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%);">+   idx = LMS_GetAntenna(m_lms_dev, LMS_CH_RX, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (idx < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Error getting Rx Antenna";</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%);">+   if (LMS_GetAntennaList(m_lms_dev, LMS_CH_RX, chan, &list) < idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Error getting Rx Antenna List";</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%);">+   return list[idx];</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 LMSDevice::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%);">+     int idx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (chan >= tx_paths.size()) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Requested non-existent 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%);">+   idx = get_ant_idx(ant, LMS_CH_TX);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (idx < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Invalid Rx Antenna";</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 (LMS_SetAntenna(m_lms_dev, LMS_CH_TX, chan, idx) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOG(ALERT) << "Unable to set Rx Antenna";</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 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 LMSDevice::getTxAntenna(size_t chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int idx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (chan >= tx_paths.size()) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Requested non-existent channel " << chan;</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%);">+   idx = LMS_GetAntenna(m_lms_dev, LMS_CH_TX, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (idx < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Error getting Tx Antenna";</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%);">+   if (LMS_GetAntennaList(m_lms_dev, LMS_CH_TX, chan, &list) < idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOG(ALERT) << "Error getting Tx Antenna List";</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%);">+   return list[idx];</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 LMSDevice::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%);">+   lms_stream_meta_t rx_metadata = {</span><br><span style="color: hsl(120, 100%, 40%);">+             .flushPartialPacket = false,</span><br><span style="color: hsl(120, 100%, 40%);">+          .waitForTimestamp = false,</span><br><span style="color: hsl(120, 100%, 40%);">+    };</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (bufs.size != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOG(ALERT) << "Invalid channel combination " << bufs.size();</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%);">+   /* Shift read time with respect to transmit clock */</span><br><span style="color: hsl(120, 100%, 40%);">+  timestamp += ts_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = LMS_RecvStream(&m_lms_stream_rx, bufs[0], len, &rx_metadata, 100);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     *overrun = false;</span><br><span style="color: hsl(120, 100%, 40%);">+     *underrun = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (LMS_GetStreamStatus(&m_lms_stream_rx, &status) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (status.underrun > m_last_rx_underruns)</span><br><span style="color: hsl(120, 100%, 40%);">+                 *underrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+             m_last_rx_underruns = status.underrun;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              if (status.overrun > m_last_rx_overruns)</span><br><span style="color: hsl(120, 100%, 40%);">+                   *overrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+              m_last_rx_overruns = status.overrun;</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 += rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return rc;</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 LMSDevice::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%);">+        lms_stream_status_t status;</span><br><span style="color: hsl(120, 100%, 40%);">+   lms_stream_meta_t tx_metadata = {</span><br><span style="color: hsl(120, 100%, 40%);">+             .flushPartialPacket = false,</span><br><span style="color: hsl(120, 100%, 40%);">+          .waitForTimestamp = true,</span><br><span style="color: hsl(120, 100%, 40%);">+             .timestamp = timestamp,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (isControl) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(ERR) << "Control packets not supported";</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 (bufs.size() != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOG(ALERT) << "Invalid channel combination " << bufs.size();</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%);">+   rc = LMS_Send_Stream(&m_lms_stream_tx, bufs[0], len, &tx_metadata, 100);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc != len) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG(ALERT) << "LMS: Device send timed out ";</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%);">+   *underrun = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (LMS_GetStreamStatus(&m_lms_stream_tx, &status) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (status.underrun > m_last_tx_underruns)</span><br><span style="color: hsl(120, 100%, 40%);">+                 *underrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+             m_last_tx_underruns = status.underrun;</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%);">+   samplesWritten += rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return rc;</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 LMSDevice::updateAlignment(TIMESTAMP timestamp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      short data[] = { 0x00, 0x02, 0x00, 0x00 };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint32_t *wordPtr = (uint32_t *) data;</span><br><span style="color: hsl(120, 100%, 40%);">+        *wordPtr = host_to_usrp_u32(*wordPtr);</span><br><span style="color: hsl(120, 100%, 40%);">+        bool tmpUnderrun;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   std::vector < short *>buf(1, data);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (writeSamples(buf, 1, &tmpUnderrun, timestamp & 0x0ffffffffll, true)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            pingTimestamp = 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%);">+     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%);">+bool LMSDevice::setTxFreq(double wFreq, size_t chan)</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 (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 (LMS_SetLOFrequency(m_lms_dev, LMS_CH_TX, chan, wFreq) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(ALERT) << "set Tx: " << wFreq << " failed!";</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%);">+   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 LMSDevice::setRxFreq(double wFreq, 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 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 (LMS_SetLOFrequency(m_lms_dev, LMS_CH_RX, chan, wFreq) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG(ALERT) << "set Rx: " << wFreq << " failed!";</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%);">+   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%);">+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 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 LMSDevice(tx_sps);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>new file mode 100644</span><br><span>index 0000000..653d159</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>@@ -0,0 +1,179 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* Copyright 2018 sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.</span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+* This use of this software may be subject to additional restrictions.</span><br><span style="color: hsl(120, 100%, 40%);">+* See the LEGAL file in the main directory for details.</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.</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%);">+#ifndef _LMS_DEVICE_H_</span><br><span style="color: hsl(120, 100%, 40%);">+#define _LMS_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 <lime/LMSDevice.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/time.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <math.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%);">+/** A class to handle a LimeSuite supported device */</span><br><span style="color: hsl(120, 100%, 40%);">+class LMSDevice:public RadioDevice {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      lms_device_t *m_lms_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+      lms_stream_t m_lms_Stream_rx;</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_stream_t m_lms_Stream_tx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       int sps;</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 LMS</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned long long samplesWritten;      ///< number of samples sent to LMS</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       bool started;           ///< flag indicates LMS has started</span><br><span style="color: hsl(120, 100%, 40%);">+        bool skipRx;            ///< set if LMS is transmit-only.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        TIMESTAMP ts_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</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%);">+     LMSDevice(size_t sps);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** Instantiate the LMS */</span><br><span style="color: hsl(120, 100%, 40%);">+    int open(const std::string &, int, bool);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /** Start the LMS */</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 LMS */</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%);">+  } enum TxWindowType getWindowType() {</span><br><span style="color: hsl(120, 100%, 40%);">+         return TX_WINDOW_LMS1;</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%);">+   Read samples from the LMS.</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 LMS 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 =</span><br><span style="color: hsl(120, 100%, 40%);">+                   NULL, 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 LMS.</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 LMS 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 =</span><br><span style="color: hsl(120, 100%, 40%);">+                    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%);">+               return 20000;</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%);">+   /** Returns the starting read Timestamp*/</span><br><span style="color: hsl(120, 100%, 40%);">+     TIMESTAMP initialReadTimestamp(void) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return 20000;</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%);">+   /** returns the full-scale transmit amplitude **/</span><br><span style="color: hsl(120, 100%, 40%);">+     double fullScaleInputValue() {</span><br><span style="color: hsl(120, 100%, 40%);">+                return 13500.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%);">+   /** returns the full-scale receive amplitude **/</span><br><span style="color: hsl(120, 100%, 40%);">+      double fullScaleOutputValue() {</span><br><span style="color: hsl(120, 100%, 40%);">+               return 9450.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%);">+   /** 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) {</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%);">+   /** 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%);">+       /** 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 internal status values */</span><br><span style="color: hsl(120, 100%, 40%);">+  inline double getTxFreq(size_t chan = 0) {</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%);">+     inline double getRxFreq(size_t chan = 0) {</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%);">+     inline double getSampleRate() {</span><br><span style="color: hsl(120, 100%, 40%);">+               return actualSampleRate;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     inline double numberRead() {</span><br><span style="color: hsl(120, 100%, 40%);">+          return samplesRead;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     inline double numberWritten() {</span><br><span style="color: hsl(120, 100%, 40%);">+               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%);">+   std::vector < std::string > tx_paths, rx_paths;</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 // _LMS_DEVICE_H_</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9599">change 9599</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/9599"/><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-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Iaef29c4c2585ef8c2f94866c9591919f538c1a2d </div>
<div style="display:none"> Gerrit-Change-Number: 9599 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>