<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-trx/+/16876">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lms: Store device type specific parameters in one place<br><br>Add an enum containing each supported device type (LimeSDR-USB,<br>LimeSDR-Mini and LimeNet-Micro) plus "unknown", to leave some room for<br>yet-to-come devices to run with some generic parameters without<br>rebuilding osmo-trx.<br><br>Each device type is assigned a dev_desc structure, and all of them are<br>put in HashMap, similar to what's already done in UHDDevice.cpp.<br><br>Device type is infered from string provided by LMS_GetDeviceInfo(), as<br>it was already done before in several places. From now on, we only need<br>to parse the string once since we store the device type after first<br>during open time.<br><br>Later on, more fields will be moved to device-type specific structure,<br>such as Tx timing offset, clock rate, etc.<br><br>Change-Id: I7658615787c5bc41c365bab9c11733b701ac2ae5<br>---<br>M Transceiver52M/device/lms/LMSDevice.cpp<br>M Transceiver52M/device/lms/LMSDevice.h<br>2 files changed, 89 insertions(+), 22 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/76/16876/1</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>index a533e7e..2e164ed 100644</span><br><span>--- a/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>@@ -20,6 +20,9 @@</span><br><span> #include <stdint.h></span><br><span> #include <string.h></span><br><span> #include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <map></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include "Logger.h"</span><br><span> #include "Threads.h"</span><br><span> #include "LMSDevice.h"</span><br><span>@@ -44,11 +47,62 @@</span><br><span> #define LMS_CALIBRATE_BW_HZ OSMO_MAX(GSM_CARRIER_BW, LMS_MIN_BW_SUPPORTED)</span><br><span> #define SAMPLE_BUF_SZ    (1 << 20) /* Size of Rx timestamp based Ring buffer, in bytes */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Device Name Prefixes as presented by LimeSuite API LMS_GetDeviceInfo(): */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LMS_DEV_SDR_USB_PREFIX_NAME "LimeSDR-USB"</span><br><span style="color: hsl(120, 100%, 40%);">+#define LMS_DEV_SDR_MINI_PREFIX_NAME "LimeSDR-Mini"</span><br><span style="color: hsl(120, 100%, 40%);">+#define LMS_DEV_NET_MICRO_PREFIX_NAME "LimeNET-Micro"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Device parameter descriptor */</span><br><span style="color: hsl(120, 100%, 40%);">+struct dev_desc {</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Does LimeSuite allow switching the clock source for this device?</span><br><span style="color: hsl(120, 100%, 40%);">+    * LimeSDR-Mini does not have switches but needs soldering to select</span><br><span style="color: hsl(120, 100%, 40%);">+   * external/internal clock. Any call to LMS_SetClockFreq() will fail.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   bool clock_src_switchable;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Does LimeSuite allow using REF_INTERNAL for this device?</span><br><span style="color: hsl(120, 100%, 40%);">+    * LimeNET-Micro does not like selecting internal clock</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+   bool clock_src_int_usable;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Device specific maximum tx levels selected by phasenoise measurements, in dB */</span><br><span style="color: hsl(120, 100%, 40%);">+    double max_tx_gain;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Device Name Prefix as presented by LimeSuite API LMS_GetDeviceInfo() */</span><br><span style="color: hsl(120, 100%, 40%);">+    std::string name_prefix;</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 const std::map<enum lms_dev_type, struct dev_desc> dev_param_map {</span><br><span style="color: hsl(120, 100%, 40%);">+       { LMS_DEV_SDR_USB,   { true,  true,  73.0, LMS_DEV_SDR_USB_PREFIX_NAME } },</span><br><span style="color: hsl(120, 100%, 40%);">+   { LMS_DEV_SDR_MINI,  { false, true,  66.0, LMS_DEV_SDR_MINI_PREFIX_NAME } },</span><br><span style="color: hsl(120, 100%, 40%);">+  { LMS_DEV_NET_MICRO, { true,  false, 71.0, LMS_DEV_NET_MICRO_PREFIX_NAME } },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LMS_DEV_UNKNOWN,   { true,  true,  73.0, "UNKNOWN" } },</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 enum lms_dev_type parse_dev_type(lms_device_t *m_lms_dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        std::map<enum lms_dev_type, struct dev_desc>::const_iterator it = dev_param_map.begin();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      const lms_dev_info_t* device_info = LMS_GetDeviceInfo(m_lms_dev);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // Iterate over the map using Iterator till end.</span><br><span style="color: hsl(120, 100%, 40%);">+      while (it != dev_param_map.end())</span><br><span style="color: hsl(120, 100%, 40%);">+     {</span><br><span style="color: hsl(120, 100%, 40%);">+             enum lms_dev_type dev_type = it->first;</span><br><span style="color: hsl(120, 100%, 40%);">+            struct dev_desc desc = it->second;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               if (strncmp(device_info->deviceName, desc.name_prefix.c_str(), desc.name_prefix.length()) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGC(DDEV, INFO) << "Device identified as " << desc.name_prefix;</span><br><span style="color: hsl(120, 100%, 40%);">+                        return dev_type;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             it++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     return LMS_DEV_UNKNOWN;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> LMSDevice::LMSDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chan_num, double lo_offset,</span><br><span>                const std::vector<std::string>& tx_paths,</span><br><span>                  const std::vector<std::string>& rx_paths):</span><br><span>    RadioDevice(tx_sps, rx_sps, iface, chan_num, lo_offset, tx_paths, rx_paths),</span><br><span style="color: hsl(0, 100%, 40%);">-    m_lms_dev(NULL), started(false)</span><br><span style="color: hsl(120, 100%, 40%);">+       m_lms_dev(NULL), started(false), dev_type(LMS_DEV_UNKNOWN)</span><br><span> {</span><br><span>      LOGC(DDEV, INFO) << "creating LMS device...";</span><br><span> </span><br><span>@@ -138,11 +192,11 @@</span><br><span> int LMSDevice::open(const std::string &args, int ref, bool swap_channels)</span><br><span> {</span><br><span>      lms_info_str_t* info_list;</span><br><span style="color: hsl(0, 100%, 40%);">-      const lms_dev_info_t* device_info;</span><br><span>   lms_range_t range_sr;</span><br><span>        float_type sr_host, sr_rf;</span><br><span>   unsigned int i, n;</span><br><span>   int rc, dev_id;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct dev_desc dev_desc;</span><br><span> </span><br><span>        LOGC(DDEV, INFO) << "Opening LMS device..";</span><br><span> </span><br><span>@@ -179,20 +233,24 @@</span><br><span> </span><br><span>  delete [] info_list;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        device_info = LMS_GetDeviceInfo(m_lms_dev);</span><br><span style="color: hsl(120, 100%, 40%);">+   dev_type = parse_dev_type(m_lms_dev);</span><br><span style="color: hsl(120, 100%, 40%);">+ dev_desc = dev_param_map.at(dev_type);</span><br><span> </span><br><span>   if ((ref != REF_EXTERNAL) && (ref != REF_INTERNAL)){</span><br><span>                 LOGC(DDEV, ERROR) << "Invalid reference type";</span><br><span>               goto out_close;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* if reference clock is external setup must happen _before_ calling LMS_Init */</span><br><span style="color: hsl(120, 100%, 40%);">+      /* if reference clock is external, setup must happen _before_ calling LMS_Init */</span><br><span>    /* FIXME make external reference frequency configurable */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (ref == REF_EXTERNAL) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (dev_desc.clock_src_switchable && ref == REF_EXTERNAL) {</span><br><span>          LOGC(DDEV, INFO) << "Setting External clock reference to 10MHz";</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 style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGC(DDEV, INFO) << "Device type " << dev_desc.name_prefix</span><br><span style="color: hsl(120, 100%, 40%);">+                               << " doesn't support switching clock source through SW";</span><br><span>        }</span><br><span> </span><br><span>        LOGC(DDEV, INFO) << "Init LMS device";</span><br><span>@@ -201,22 +259,23 @@</span><br><span>               goto out_close;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* LimeSDR-Mini does not have switches but needs soldering to select external/internal clock */</span><br><span style="color: hsl(0, 100%, 40%);">- /* LimeNET-Micro also does not like selecting internal clock*/</span><br><span style="color: hsl(0, 100%, 40%);">-  /* also set device specific maximum tx levels selected by phasenoise measurements*/</span><br><span style="color: hsl(0, 100%, 40%);">-     if (strncmp(device_info->deviceName,"LimeSDR-USB",11) == 0){</span><br><span style="color: hsl(0, 100%, 40%);">-               /* if reference clock is internal setup must happen _after_ calling LMS_Init */</span><br><span style="color: hsl(0, 100%, 40%);">-         /* according to lms using LMS_CLOCK_EXTREF with a frequency <= 0 is the correct way to set clock to internal reference*/</span><br><span style="color: hsl(0, 100%, 40%);">-             if (ref == REF_INTERNAL) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGC(DDEV, INFO) << "Setting Internal clock reference";</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, -1) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                           goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* if reference clock is internal, setup must happen _after_ calling LMS_Init */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (dev_desc.clock_src_switchable && ref == REF_INTERNAL) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGC(DDEV, INFO) << "Setting Internal clock reference";</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!dev_desc.clock_src_int_usable) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 LOGC(DDEV, ERROR) << "Device type " << dev_desc.name_prefix</span><br><span style="color: hsl(120, 100%, 40%);">+                                       << " doesn't support internal reference clock";</span><br><span style="color: hsl(120, 100%, 40%);">+                 goto out_close;</span><br><span>              }</span><br><span style="color: hsl(0, 100%, 40%);">-               maxTxGainClamp = 73.0;</span><br><span style="color: hsl(0, 100%, 40%);">-  } else if (strncmp(device_info->deviceName,"LimeSDR-Mini",12) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                maxTxGainClamp = 66.0;</span><br><span style="color: hsl(0, 100%, 40%);">-  else</span><br><span style="color: hsl(0, 100%, 40%);">-            maxTxGainClamp = 71.0; /* "LimeNET-Micro", etc FIXME pciE based LMS boards?*/</span><br><span style="color: hsl(120, 100%, 40%);">+               /* According to lms using LMS_CLOCK_EXTREF with a</span><br><span style="color: hsl(120, 100%, 40%);">+                frequency <= 0 is the correct way to set clock to</span><br><span style="color: hsl(120, 100%, 40%);">+                  internal reference*/</span><br><span style="color: hsl(120, 100%, 40%);">+               if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, -1) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                 goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGC(DDEV, INFO) << "Device type " << dev_desc.name_prefix</span><br><span style="color: hsl(120, 100%, 40%);">+                               << " doesn't support switching clock source through SW";</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span>        /* enable all used channels */</span><br><span>       for (i=0; i<chans; i++) {</span><br><span>@@ -383,7 +442,7 @@</span><br><span> </span><br><span> double LMSDevice::maxTxGain()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    return maxTxGainClamp;</span><br><span style="color: hsl(120, 100%, 40%);">+        return dev_param_map.at(dev_type).max_tx_gain;</span><br><span> }</span><br><span> </span><br><span> double LMSDevice::minTxGain()</span><br><span>diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>index cdba72c..2489539 100644</span><br><span>--- a/Transceiver52M/device/lms/LMSDevice.h</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>@@ -41,6 +41,13 @@</span><br><span>  *    A^2 = 1 */</span><br><span> #define LIMESDR_TX_AMPL  0.707</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum lms_dev_type {</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_DEV_SDR_USB,   /* LimeSDR-USB */</span><br><span style="color: hsl(120, 100%, 40%);">+  LMS_DEV_SDR_MINI,  /* LimeSDR-Mini */</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_DEV_NET_MICRO, /* LimeNet-micro */</span><br><span style="color: hsl(120, 100%, 40%);">+        LMS_DEV_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /** A class to handle a LimeSuite supported device */</span><br><span> class LMSDevice:public RadioDevice {</span><br><span> </span><br><span>@@ -59,7 +66,8 @@</span><br><span>      TIMESTAMP ts_initial, ts_offset;</span><br><span> </span><br><span>         std::vector<double> tx_gains, rx_gains;</span><br><span style="color: hsl(0, 100%, 40%);">-   double maxTxGainClamp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      enum lms_dev_type dev_type;</span><br><span> </span><br><span>      bool do_calib(size_t chan);</span><br><span>  bool do_filters(size_t chan);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-trx/+/16876">change 16876</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-trx/+/16876"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I7658615787c5bc41c365bab9c11733b701ac2ae5 </div>
<div style="display:none"> Gerrit-Change-Number: 16876 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>