<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/9600">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lms: Several improvements and compilation/runtime fixes<br><br>Continuation of initial work done on LimeSuite support from Harald.<br><br>Change-Id: Ib2fca81b76d027b08e2891056fa076d071597783<br>---<br>M CommonLibs/Logger.h<br>M CommonLibs/debug.c<br>M CommonLibs/debug.h<br>M Transceiver52M/device/lms/LMSDevice.cpp<br>M Transceiver52M/device/lms/LMSDevice.h<br>M Transceiver52M/device/radioDevice.h<br>6 files changed, 274 insertions(+), 127 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/00/9600/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CommonLibs/Logger.h b/CommonLibs/Logger.h</span><br><span>index 5b0b05c..e18ecfb 100644</span><br><span>--- a/CommonLibs/Logger.h</span><br><span>+++ b/CommonLibs/Logger.h</span><br><span>@@ -53,6 +53,9 @@</span><br><span> #define LOGC(category, level) \</span><br><span> Log(category, LOGL_##level, __BASE_FILE__, __LINE__).get() << "[tid=" << pthread_self() << "] "</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGLV(category, level) \</span><br><span style="color: hsl(120, 100%, 40%);">+ Log(category, level, __BASE_FILE__, __LINE__).get() << "[tid=" << pthread_self() << "] "</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /**</span><br><span> A C++ stream-based thread-safe logger.</span><br><span> This object is NOT the global logger;</span><br><span>diff --git a/CommonLibs/debug.c b/CommonLibs/debug.c</span><br><span>index e4db2f3..01854c0 100644</span><br><span>--- a/CommonLibs/debug.c</span><br><span>+++ b/CommonLibs/debug.c</span><br><span>@@ -10,6 +10,12 @@</span><br><span> .color = NULL,</span><br><span> .enabled = 1, .loglevel = LOGL_NOTICE,</span><br><span> },</span><br><span style="color: hsl(120, 100%, 40%);">+ [DLMS] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "DLMS",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "LimeSuite category",</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+ .enabled = 1, .loglevel = LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span> };</span><br><span> </span><br><span> const struct log_info log_info = {</span><br><span>diff --git a/CommonLibs/debug.h b/CommonLibs/debug.h</span><br><span>index 7038f4c..06ad74e 100644</span><br><span>--- a/CommonLibs/debug.h</span><br><span>+++ b/CommonLibs/debug.h</span><br><span>@@ -5,4 +5,5 @@</span><br><span> /* Debug Areas of the code */</span><br><span> enum {</span><br><span> DMAIN,</span><br><span style="color: hsl(120, 100%, 40%);">+ DLMS,</span><br><span> };</span><br><span>diff --git a/Transceiver52M/device/lms/LMSDevice.cpp b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>index ed51cdb..603b23d 100644</span><br><span>--- a/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>@@ -24,26 +24,40 @@</span><br><span> </span><br><span> #include <lime/LimeSuite.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifdef HAVE_CONFIG_H</span><br><span> #include "config.h"</span><br><span> #endif</span><br><span> </span><br><span> using namespace std;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-const double LMSDevice::masterClockRate = 52.0e6;</span><br><span style="color: hsl(120, 100%, 40%);">+constexpr double LMSDevice::masterClockRate;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-LMSDevice::LMSDevice(size_t sps)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_ANTENNA_LIST_SIZE 10</span><br><span style="color: hsl(120, 100%, 40%);">+#define LMS_SAMPLE_RATE GSMRATE*32</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSM_CARRIER_BW 270000.0 /* 270kHz */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LMS_MIN_BW_SUPPORTED 2.5e6 /* 2.5mHz, minimum supported by LMS */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LMS_CALIBRATE_BW_HZ OSMO_MAX(GSM_CARRIER_BW, LMS_MIN_BW_SUPPORTED)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+LMSDevice::LMSDevice(size_t sps, size_t chans):</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_dev(NULL), sps(sps), chans(chans)</span><br><span> {</span><br><span> LOG(INFO) << "creating LMS device...";</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- m_lms_device = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- this->sps = sps;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx.resize(chans);</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_tx.resize(chans);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_rx_underruns.resize(chans, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_rx_overruns.resize(chans, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_tx_underruns.resize(chans, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_tx_overruns.resize(chans, 0);</span><br><span> }</span><br><span> </span><br><span> static void lms_log_callback(int lvl, const char *msg)</span><br><span> {</span><br><span> /* map lime specific log levels */</span><br><span style="color: hsl(0, 100%, 40%);">- static const lvl_map[4] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ static const int lvl_map[5] = {</span><br><span> [0] = LOGL_FATAL,</span><br><span> [1] = LOGL_ERROR,</span><br><span> [2] = LOGL_NOTICE,</span><br><span>@@ -51,40 +65,71 @@</span><br><span> [4] = LOGL_DEBUG,</span><br><span> };</span><br><span> /* protect against future higher log level values (lower importance) */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lvl >= ARRAY_SIZE(lvl_map))</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((unsigned int) lvl >= ARRAY_SIZE(lvl_map))</span><br><span> lvl = ARRAY_SIZE(lvl_map)-1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOG(lvl) << msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGLV(DLMS, lvl) << msg;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int LMSDevice::open(const std::string &, int, bool)</span><br><span style="color: hsl(120, 100%, 40%);">+static void thread_enable_cancel(bool cancel)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- lms_info_str dev_str;</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t dac_val;</span><br><span style="color: hsl(120, 100%, 40%);">+ cancel ? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) :</span><br><span style="color: hsl(120, 100%, 40%);">+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOG(INFO) << "opening LMS device..";</span><br><span style="color: hsl(120, 100%, 40%);">+int LMSDevice::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%);">+ //lms_info_str_t dev_str;</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_info_str_t* info_list;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t dac_val;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i, n;</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%);">+ LOG(INFO) << "Opening LMS device..";</span><br><span> </span><br><span> LMS_RegisterLogHandler(&lms_log_callback);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- rc = LMS_Open(&m_lms_dev, NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc != 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((n = LMS_GetDeviceList(NULL)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(ERROR) << "LMS_GetDeviceList(NULL) failed";</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Devices found: " << n;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (n < 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_SetSampleRate(m_lms_dev, GSMRATE, sps) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ info_list = new lms_info_str_t[n];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_GetDeviceList(info_list) < 0) //Populate device list</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(ERROR) << "LMS_GetDeviceList(info_list) failed";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < n; i++) //print device list</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Device [" << i << "]: " << info_list[i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = LMS_Open(&m_lms_dev, info_list[0], NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(ERROR) << "LMS_GetDeviceList() failed)";</span><br><span style="color: hsl(120, 100%, 40%);">+ delete [] info_list;</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%);">+ delete [] info_list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Setting sample rate to " << GSMRATE*sps << " " << sps;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_SetSampleRate(m_lms_dev, GSMRATE*sps, 32) < 0)</span><br><span> goto out_close;</span><br><span> /* FIXME: make this device/model dependent, like UHDDevice:dev_param_map! */</span><br><span style="color: hsl(0, 100%, 40%);">- ts_offset = static_caset<TIMESTAMP>(8.9e-5 * GSMRATE);</span><br><span style="color: hsl(120, 100%, 40%);">+ ts_offset = static_cast<TIMESTAMP>(8.9e-5 * GSMRATE);</span><br><span> </span><br><span> switch (ref) {</span><br><span> case REF_INTERNAL:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Setting Internal clock reference";</span><br><span> /* Ugly API: Selecting clock source implicit by writing to VCTCXO DAC ?!? */</span><br><span> if (LMS_VCTCXORead(m_lms_dev, &dac_val) < 0)</span><br><span> goto out_close;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Setting VCTCXO to " << dac_val;</span><br><span> if (LMS_VCTCXOWrite(m_lms_dev, dac_val) < 0)</span><br><span> goto out_close;</span><br><span> break;</span><br><span style="color: hsl(0, 100%, 40%);">- case REF_EXTENAL:</span><br><span style="color: hsl(120, 100%, 40%);">+ case REF_EXTERNAL:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Setting Internal clock reference to " << 10000000.0;</span><br><span> /* Assume an external 10 MHz reference clock */</span><br><span> if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, 10000000.0) < 0)</span><br><span> goto out_close;</span><br><span>@@ -94,14 +139,18 @@</span><br><span> goto out_close;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(INFO) << "Init LMS device";</span><br><span> if (LMS_Init(m_lms_dev) < 0)</span><br><span> goto out_close;</span><br><span> </span><br><span> /* Perform Rx and Tx calibration */</span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_Calibrate(m_lms_dev, LMS_CH_RX, chan, 270000.0, 0) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- goto out_close;</span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_Calibrate(m_lms_dev, LMS_CH_TX, chan, 270000.0, 0) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i=0; i<chans; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(INFO) << "Calibrating chan " << i;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_Calibrate(m_lms_dev, LMS_CH_RX, i, LMS_CALIBRATE_BW_HZ, 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, i, LMS_CALIBRATE_BW_HZ, 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> </span><br><span> samplesRead = 0;</span><br><span> samplesWritten = 0;</span><br><span>@@ -119,42 +168,47 @@</span><br><span> {</span><br><span> LOG(INFO) << "starting LMS...";</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_EnableChannel(m_lms_dev, LMS_CH_RX, 0, true) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_EnableChannel(m_lms_dev, LMS_CH_TX, 0, true) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i=0; i<chans; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_EnableChannel(m_lms_dev, LMS_CH_RX, i, true) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- // Set gains to midpoint</span><br><span style="color: hsl(0, 100%, 40%);">- setTxGain((minTxGain() + maxTxGain()) / 2);</span><br><span style="color: hsl(0, 100%, 40%);">- setRxGain((minRxGain() + maxRxGain()) / 2);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_EnableChannel(m_lms_dev, LMS_CH_TX, i, true) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- m_lms_stream_rx = {</span><br><span style="color: hsl(0, 100%, 40%);">- .isTx = false,</span><br><span style="color: hsl(0, 100%, 40%);">- .channel = 0,</span><br><span style="color: hsl(0, 100%, 40%);">- .fifoSize = 1024 * 1024,</span><br><span style="color: hsl(0, 100%, 40%);">- .throughputVsLatency = 0.3,</span><br><span style="color: hsl(0, 100%, 40%);">- .dataFmt = LMS_FMT_I16,</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- m_lms_stream_tx = {</span><br><span style="color: hsl(0, 100%, 40%);">- .ixTx = true,</span><br><span style="color: hsl(0, 100%, 40%);">- .channel = 0,</span><br><span style="color: hsl(0, 100%, 40%);">- .fifoSize = 1024 * 1024,</span><br><span style="color: hsl(0, 100%, 40%);">- .throughputVsLatency = 0.3,</span><br><span style="color: hsl(0, 100%, 40%);">- .dataFmt = LMS_FMT_I16,</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, i);</span><br><span style="color: hsl(120, 100%, 40%);">+ setRxGain((minRxGain() + maxRxGain()) / 2, i);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx[i] = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx[i].isTx = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx[i].channel = i;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx[i].fifoSize = 1024 * 1024;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx[i].throughputVsLatency = 0.3;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_rx[i].dataFmt = lms_stream_t::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[i] = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_tx[i].isTx = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_tx[i].channel = i;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_tx[i].fifoSize = 1024 * 1024;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_tx[i].throughputVsLatency = 0.3;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_lms_stream_tx[i].dataFmt = lms_stream_t::LMS_FMT_I16;</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[i]) < 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[i]) < 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[i]) < 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[i]) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_SetupStream(m_lms_dev, &m_lms_stream_rx) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_SetupStream(m_lms_dev, &m_lms_stream_tx) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_StartStream(&m_lms_stream_rx) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_StartStream(&m_lms_stream_tx) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ flush_recv(10);</span><br><span> </span><br><span> started = true;</span><br><span> return true;</span><br><span>@@ -162,14 +216,18 @@</span><br><span> </span><br><span> bool LMSDevice::stop()</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (!started)</span><br><span> return true;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LMS_StopStream(&m_lms_stream_tx);</span><br><span style="color: hsl(0, 100%, 40%);">- LMS_StopStream(&m_lms_stream_rx);</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i=0; i<chans; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_StopStream(&m_lms_stream_tx[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_StopStream(&m_lms_stream_rx[i]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LMS_EnableChannel(m_lms_dev, LMS_CH_RX, 0, false);</span><br><span style="color: hsl(0, 100%, 40%);">- LMS_EnableChannel(m_lms_dev, LMS_CH_TX, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_EnableChannel(m_lms_dev, LMS_CH_RX, i, false);</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_EnableChannel(m_lms_dev, LMS_CH_TX, i, false);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span> return true;</span><br><span> }</span><br><span>@@ -236,18 +294,50 @@</span><br><span> return dB;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int get_ant_idx(const char *name, bool dir_tx)</span><br><span style="color: hsl(120, 100%, 40%);">+int LMSDevice::get_ant_idx(const std::string & name, bool dir_tx, size_t chan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- lms_name_t name_list;</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_name_t name_list[MAX_ANTENNA_LIST_SIZE]; /* large enough list for antenna names. */</span><br><span style="color: hsl(120, 100%, 40%);">+ const char* c_name = name.c_str();</span><br><span> int num_names;</span><br><span style="color: hsl(0, 100%, 40%);">- num_names = LMS_GetAntennaList(m_lms_dev, dir_tx, &name_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ num_names = LMS_GetAntennaList(m_lms_dev, dir_tx, chan, name_list);</span><br><span> for (i = 0; i < num_names; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcmp(name, name_list[i]))</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(c_name, name_list[i]))</span><br><span> return i;</span><br><span> }</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+bool LMSDevice::flush_recv(size_t num_pkts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ #define CHUNK 625</span><br><span style="color: hsl(120, 100%, 40%);">+ int len = CHUNK * sps;</span><br><span style="color: hsl(120, 100%, 40%);">+ short *buffer = new short[len * 2];</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_stream_meta_t rx_metadata = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ rx_metadata.flushPartialPacket = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ rx_metadata.waitForTimestamp = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ts_initial = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (!ts_initial || (num_pkts-- > 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = LMS_RecvStream(&m_lms_stream_rx[0], &buffer[0], len, &rx_metadata, 100);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(DEBUG) << "Flush: Recv buffer of len " << rc << " at " << std::hex << rx_metadata.timestamp;</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 receive timed out";</span><br><span style="color: hsl(120, 100%, 40%);">+ delete[] buffer;</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%);">+ ts_initial = rx_metadata.timestamp;</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%);">+ LOG(INFO) << "Initial timestamp " << ts_initial << std::endl;</span><br><span style="color: hsl(120, 100%, 40%);">+ delete[] buffer;</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> bool LMSDevice::setRxAntenna(const std::string & ant, size_t chan)</span><br><span> {</span><br><span> int idx;</span><br><span>@@ -257,7 +347,7 @@</span><br><span> return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- idx = get_ant_idx(ant, LMS_CH_RX);</span><br><span style="color: hsl(120, 100%, 40%);">+ idx = get_ant_idx(ant, LMS_CH_RX, chan);</span><br><span> if (idx < 0) {</span><br><span> LOG(ALERT) << "Invalid Rx Antenna";</span><br><span> return false;</span><br><span>@@ -272,6 +362,9 @@</span><br><span> </span><br><span> std::string LMSDevice::getRxAntenna(size_t chan)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_name_t name_list[MAX_ANTENNA_LIST_SIZE]; /* large enough list for antenna names. */</span><br><span style="color: hsl(120, 100%, 40%);">+ int idx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (chan >= rx_paths.size()) {</span><br><span> LOG(ALERT) << "Requested non-existent channel " << chan;</span><br><span> return "";</span><br><span>@@ -283,12 +376,12 @@</span><br><span> return "";</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_GetAntennaList(m_lms_dev, LMS_CH_RX, chan, &list) < idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_GetAntennaList(m_lms_dev, LMS_CH_RX, chan, name_list) < idx) {</span><br><span> LOG(ALERT) << "Error getting Rx Antenna List";</span><br><span> return "";</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- return list[idx];</span><br><span style="color: hsl(120, 100%, 40%);">+ return name_list[idx];</span><br><span> }</span><br><span> </span><br><span> bool LMSDevice::setTxAntenna(const std::string & ant, size_t chan)</span><br><span>@@ -300,7 +393,7 @@</span><br><span> return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- idx = get_ant_idx(ant, LMS_CH_TX);</span><br><span style="color: hsl(120, 100%, 40%);">+ idx = get_ant_idx(ant, LMS_CH_TX, chan);</span><br><span> if (idx < 0) {</span><br><span> LOG(ALERT) << "Invalid Rx Antenna";</span><br><span> return false;</span><br><span>@@ -315,6 +408,7 @@</span><br><span> </span><br><span> std::string LMSDevice::getTxAntenna(size_t chan)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_name_t name_list[MAX_ANTENNA_LIST_SIZE]; /* large enough list for antenna names. */</span><br><span> int idx;</span><br><span> </span><br><span> if (chan >= tx_paths.size()) {</span><br><span>@@ -328,49 +422,73 @@</span><br><span> return "";</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_GetAntennaList(m_lms_dev, LMS_CH_TX, chan, &list) < idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_GetAntennaList(m_lms_dev, LMS_CH_TX, chan, name_list) < idx) {</span><br><span> LOG(ALERT) << "Error getting Tx Antenna List";</span><br><span> return "";</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- return list[idx];</span><br><span style="color: hsl(120, 100%, 40%);">+ return name_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::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 LMSDevice::minLatency() {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Empirical data from a handful of</span><br><span style="color: hsl(120, 100%, 40%);">+ relatively recent machines shows that the B100 will underrun when</span><br><span style="color: hsl(120, 100%, 40%);">+ the transmit threshold is reduced to a time of 6 and a half frames,</span><br><span style="color: hsl(120, 100%, 40%);">+ so we set a minimum 7 frame threshold. */</span><br><span style="color: hsl(120, 100%, 40%);">+ return GSM::Time(6,7);</span><br><span> }</span><br><span> </span><br><span> // NOTE: Assumes sequential reads</span><br><span> int LMSDevice::readSamples(std::vector < short *>&bufs, int len, bool * overrun,</span><br><span> TIMESTAMP timestamp, bool * underrun, unsigned *RSSI)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- lms_stream_meta_t rx_metadata = {</span><br><span style="color: hsl(0, 100%, 40%);">- .flushPartialPacket = false,</span><br><span style="color: hsl(0, 100%, 40%);">- .waitForTimestamp = false,</span><br><span style="color: hsl(0, 100%, 40%);">- };</span><br><span style="color: hsl(0, 100%, 40%);">- int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</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 rx_metadata = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ rx_metadata.flushPartialPacket = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ rx_metadata.waitForTimestamp = false;</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%);">+ rx_metadata.timestamp = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (bufs.size != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bufs.size() != chans) {</span><br><span> LOG(ALERT) << "Invalid channel combination " << bufs.size();</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Shift read time with respect to transmit clock */</span><br><span style="color: hsl(0, 100%, 40%);">- timestamp += ts_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rc = LMS_RecvStream(&m_lms_stream_rx, bufs[0], len, &rx_metadata, 100);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> *overrun = false;</span><br><span> *underrun = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i<chans; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ thread_enable_cancel(false);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = LMS_RecvStream(&m_lms_stream_rx[i], bufs[i], len, &rx_metadata, 100);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(ALERT) << "chan "<< i << " recv buffer of len " << rc << " expect " << std::hex << timestamp << " got " << std::hex << (TIMESTAMP)rx_metadata.timestamp << " (" << std::hex << rx_metadata.timestamp <<") diff=" << rx_metadata.timestamp - timestamp;</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 receive timed out";</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_GetStreamStatus(&m_lms_stream_rx, &status) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (status.underrun > m_last_rx_underruns)</span><br><span style="color: hsl(0, 100%, 40%);">- *underrun = true;</span><br><span style="color: hsl(0, 100%, 40%);">- m_last_rx_underruns = status.underrun;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_GetStreamStatus(&m_lms_stream_rx[i], &status) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (status.underrun > m_last_rx_underruns[i])</span><br><span style="color: hsl(120, 100%, 40%);">+ *underrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_rx_underruns[i] = status.underrun;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (status.overrun > m_last_rx_overruns)</span><br><span style="color: hsl(0, 100%, 40%);">- *overrun = true;</span><br><span style="color: hsl(0, 100%, 40%);">- m_last_rx_overruns = status.overrun;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (status.overrun > m_last_rx_overruns[i])</span><br><span style="color: hsl(120, 100%, 40%);">+ *overrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_rx_overruns[i] = status.overrun;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ thread_enable_cancel(true);</span><br><span> }</span><br><span> </span><br><span> samplesRead += rc;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (((TIMESTAMP) rx_metadata.timestamp) < timestamp)</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return rc;</span><br><span> }</span><br><span> </span><br><span>@@ -378,35 +496,40 @@</span><br><span> bool * underrun, unsigned long long timestamp,</span><br><span> bool isControl)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- lms_stream_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">- lms_stream_meta_t tx_metadata = {</span><br><span style="color: hsl(0, 100%, 40%);">- .flushPartialPacket = false,</span><br><span style="color: hsl(0, 100%, 40%);">- .waitForTimestamp = true,</span><br><span style="color: hsl(0, 100%, 40%);">- .timestamp = timestamp,</span><br><span style="color: hsl(0, 100%, 40%);">- };</span><br><span> int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</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%);">+ tx_metadata.flushPartialPacket = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ tx_metadata.waitForTimestamp = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ tx_metadata.timestamp = timestamp;</span><br><span> </span><br><span> if (isControl) {</span><br><span> LOG(ERR) << "Control packets not supported";</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (bufs.size() != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bufs.size() != chans) {</span><br><span> LOG(ALERT) << "Invalid channel combination " << bufs.size();</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- rc = LMS_Send_Stream(&m_lms_stream_tx, bufs[0], len, &tx_metadata, 100);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc != len) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOG(ALERT) << "LMS: Device send timed out ";</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> *underrun = false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_GetStreamStatus(&m_lms_stream_tx, &status) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (status.underrun > m_last_tx_underruns)</span><br><span style="color: hsl(0, 100%, 40%);">- *underrun = true;</span><br><span style="color: hsl(0, 100%, 40%);">- m_last_tx_underruns = status.underrun;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i<chans; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG(ALERT) << "chan "<< i << " send buffer of len " << len << " timestamp " << std::hex << tx_metadata.timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+ thread_enable_cancel(false);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = LMS_SendStream(&m_lms_stream_tx[i], bufs[i], 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%);">+ if (LMS_GetStreamStatus(&m_lms_stream_tx[i], &status) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (status.underrun > m_last_tx_underruns[i])</span><br><span style="color: hsl(120, 100%, 40%);">+ *underrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ m_last_tx_underruns[i] = status.underrun;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ thread_enable_cancel(true);</span><br><span> }</span><br><span> </span><br><span> samplesWritten += rc;</span><br><span>@@ -416,17 +539,7 @@</span><br><span> </span><br><span> bool LMSDevice::updateAlignment(TIMESTAMP timestamp)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- short data[] = { 0x00, 0x02, 0x00, 0x00 };</span><br><span style="color: hsl(0, 100%, 40%);">- uint32_t *wordPtr = (uint32_t *) data;</span><br><span style="color: hsl(0, 100%, 40%);">- *wordPtr = host_to_usrp_u32(*wordPtr);</span><br><span style="color: hsl(0, 100%, 40%);">- bool tmpUnderrun;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- std::vector < short *>buf(1, data);</span><br><span style="color: hsl(0, 100%, 40%);">- if (writeSamples(buf, 1, &tmpUnderrun, timestamp & 0x0ffffffffll, true)) {</span><br><span style="color: hsl(0, 100%, 40%);">- pingTimestamp = timestamp;</span><br><span style="color: hsl(0, 100%, 40%);">- return true;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</span><br><span> }</span><br><span> </span><br><span> bool LMSDevice::setTxFreq(double wFreq, size_t chan)</span><br><span>@@ -465,5 +578,5 @@</span><br><span> const std::vector < std::string > &tx_paths,</span><br><span> const std::vector < std::string > &rx_paths)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return new LMSDevice(tx_sps);</span><br><span style="color: hsl(120, 100%, 40%);">+ return new LMSDevice(tx_sps, chans);</span><br><span> }</span><br><span>diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>index 653d159..99eed43 100644</span><br><span>--- a/Transceiver52M/device/lms/LMSDevice.h</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>@@ -21,22 +21,33 @@</span><br><span> </span><br><span> #include "radioDevice.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <lime/LMSDevice.h></span><br><span> #include <sys/time.h></span><br><span> #include <math.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <limits.h></span><br><span> #include <string></span><br><span> #include <iostream></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%);">+#define LIMESDR_TX_AMPL 0.3</span><br><span> </span><br><span> /** A class to handle a LimeSuite supported device */</span><br><span> class LMSDevice:public RadioDevice {</span><br><span> </span><br><span> private:</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- lms_device_t *m_lms_dev;</span><br><span style="color: hsl(0, 100%, 40%);">- lms_stream_t m_lms_Stream_rx;</span><br><span style="color: hsl(0, 100%, 40%);">- lms_stream_t m_lms_Stream_tx;</span><br><span style="color: hsl(120, 100%, 40%);">+ static constexpr double masterClockRate = 52.0e6;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- int sps;</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_device_t *m_lms_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+ std::vector<lms_stream_t> m_lms_stream_rx;</span><br><span style="color: hsl(120, 100%, 40%);">+ std::vector<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%);">+ std::vector<uint32_t> m_last_rx_underruns;</span><br><span style="color: hsl(120, 100%, 40%);">+ std::vector<uint32_t> m_last_rx_overruns;</span><br><span style="color: hsl(120, 100%, 40%);">+ std::vector<uint32_t> m_last_tx_underruns;</span><br><span style="color: hsl(120, 100%, 40%);">+ std::vector<uint32_t> m_last_tx_overruns;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t sps, chans;</span><br><span style="color: hsl(120, 100%, 40%);">+ double actualSampleRate; ///< the actual USRP sampling rate</span><br><span> </span><br><span> unsigned long long samplesRead; ///< number of samples read from LMS</span><br><span> unsigned long long samplesWritten; ///< number of samples sent to LMS</span><br><span>@@ -44,15 +55,20 @@</span><br><span> bool started; ///< flag indicates LMS has started</span><br><span> bool skipRx; ///< set if LMS is transmit-only.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- TIMESTAMP ts_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+ TIMESTAMP ts_initial, ts_offset;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int get_ant_idx(const std::string & name, bool dir_tx, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ bool flush_recv(size_t num_pkts);</span><br><span> </span><br><span> public:</span><br><span> </span><br><span> /** Object constructor */</span><br><span style="color: hsl(0, 100%, 40%);">- LMSDevice(size_t sps);</span><br><span style="color: hsl(120, 100%, 40%);">+ LMSDevice(size_t sps, size_t chans);</span><br><span> </span><br><span> /** Instantiate the LMS */</span><br><span style="color: hsl(0, 100%, 40%);">- int open(const std::string &, int, bool);</span><br><span style="color: hsl(120, 100%, 40%);">+ int open(const std::string &args, int ref, bool swap_channels);</span><br><span> </span><br><span> /** Start the LMS */</span><br><span> bool start();</span><br><span>@@ -62,7 +78,9 @@</span><br><span> </span><br><span> /** Set priority not supported */</span><br><span> void setPriority(float prio = 0.5) {</span><br><span style="color: hsl(0, 100%, 40%);">- } enum TxWindowType getWindowType() {</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%);">+ enum TxWindowType getWindowType() {</span><br><span> return TX_WINDOW_LMS1;</span><br><span> }</span><br><span> </span><br><span>@@ -103,22 +121,22 @@</span><br><span> </span><br><span> /** Returns the starting write Timestamp*/</span><br><span> TIMESTAMP initialWriteTimestamp(void) {</span><br><span style="color: hsl(0, 100%, 40%);">- return 20000;</span><br><span style="color: hsl(120, 100%, 40%);">+ return ts_initial;</span><br><span> }</span><br><span> </span><br><span> /** Returns the starting read Timestamp*/</span><br><span> TIMESTAMP initialReadTimestamp(void) {</span><br><span style="color: hsl(0, 100%, 40%);">- return 20000;</span><br><span style="color: hsl(120, 100%, 40%);">+ return ts_initial;</span><br><span> }</span><br><span> </span><br><span> /** returns the full-scale transmit amplitude **/</span><br><span> double fullScaleInputValue() {</span><br><span style="color: hsl(0, 100%, 40%);">- return 13500.0;</span><br><span style="color: hsl(120, 100%, 40%);">+ return(double) SHRT_MAX * LIMESDR_TX_AMPL;</span><br><span> }</span><br><span> </span><br><span> /** returns the full-scale receive amplitude **/</span><br><span> double fullScaleOutputValue() {</span><br><span style="color: hsl(0, 100%, 40%);">- return 9450.0;</span><br><span style="color: hsl(120, 100%, 40%);">+ return (double) SHRT_MAX;</span><br><span> }</span><br><span> </span><br><span> /** sets the receive chan gain, returns the gain setting **/</span><br><span>@@ -156,6 +174,12 @@</span><br><span> /* return the used RX path */</span><br><span> std::string getTxAntenna(size_t chan = 0);</span><br><span> </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> /** Return internal status values */</span><br><span> inline double getTxFreq(size_t chan = 0) {</span><br><span> return 0;</span><br><span>diff --git a/Transceiver52M/device/radioDevice.h b/Transceiver52M/device/radioDevice.h</span><br><span>index 44636d5..c5cd461 100644</span><br><span>--- a/Transceiver52M/device/radioDevice.h</span><br><span>+++ b/Transceiver52M/device/radioDevice.h</span><br><span>@@ -39,7 +39,7 @@</span><br><span> </span><br><span> public:</span><br><span> /* Available transport bus types */</span><br><span style="color: hsl(0, 100%, 40%);">- enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED };</span><br><span style="color: hsl(120, 100%, 40%);">+ enum TxWindowType { TX_WINDOW_USRP1, TX_WINDOW_FIXED, TX_WINDOW_LMS1 };</span><br><span> </span><br><span> /* Radio interface types */</span><br><span> enum InterfaceType {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9600">change 9600</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/9600"/><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: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ib2fca81b76d027b08e2891056fa076d071597783 </div>
<div style="display:none"> Gerrit-Change-Number: 9600 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>