Change in osmo-trx[master]: lms: Store device type specific parameters in one place

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Thu Jan 16 13:09:40 UTC 2020


pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-trx/+/16876 )

Change subject: lms: Store device type specific parameters in one place
......................................................................

lms: Store device type specific parameters in one place

Add an enum containing each supported device type (LimeSDR-USB,
LimeSDR-Mini and LimeNet-Micro) plus "unknown", to leave some room for
yet-to-come devices to run with some generic parameters without
rebuilding osmo-trx.

Each device type is assigned a dev_desc structure, and all of them are
put in HashMap, similar to what's already done in UHDDevice.cpp.

Device type is infered from string provided by LMS_GetDeviceInfo(), as
it was already done before in several places. From now on, we only need
to parse the string once since we store the device type after first
during open time.

Later on, more fields will be moved to device-type specific structure,
such as Tx timing offset, clock rate, etc.

Change-Id: I7658615787c5bc41c365bab9c11733b701ac2ae5
---
M CommonLibs/trx_vty.c
M CommonLibs/trx_vty.h
M Transceiver52M/device/lms/LMSDevice.cpp
M Transceiver52M/device/lms/LMSDevice.h
4 files changed, 119 insertions(+), 26 deletions(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  fixeria: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/CommonLibs/trx_vty.c b/CommonLibs/trx_vty.c
index 44e1d31..3f875f5 100644
--- a/CommonLibs/trx_vty.c
+++ b/CommonLibs/trx_vty.c
@@ -42,7 +42,7 @@
 
 static struct trx_ctx* g_trx_ctx;
 
-static const struct value_string clock_ref_names[] = {
+const struct value_string clock_ref_names[] = {
 	{ REF_INTERNAL,	"internal" },
 	{ REF_EXTERNAL,	"external" },
 	{ REF_GPS,	"gpsdo" },
diff --git a/CommonLibs/trx_vty.h b/CommonLibs/trx_vty.h
index d20dd96..c0d54cf 100644
--- a/CommonLibs/trx_vty.h
+++ b/CommonLibs/trx_vty.h
@@ -5,6 +5,7 @@
 #include "config_defs.h"
 
 extern struct vty_app_info g_vty_info;
+extern const struct value_string clock_ref_names[];
 extern const struct value_string filler_names[];
 
 /* Maximum number of physical RF channels */
diff --git a/Transceiver52M/device/lms/LMSDevice.cpp b/Transceiver52M/device/lms/LMSDevice.cpp
index 8ad338b..1ef7728 100644
--- a/Transceiver52M/device/lms/LMSDevice.cpp
+++ b/Transceiver52M/device/lms/LMSDevice.cpp
@@ -20,6 +20,10 @@
 #include <stdint.h>
 #include <string.h>
 #include <stdlib.h>
+
+#include <map>
+
+#include "trx_vty.h"
 #include "Logger.h"
 #include "Threads.h"
 #include "LMSDevice.h"
@@ -44,11 +48,61 @@
 #define LMS_CALIBRATE_BW_HZ OSMO_MAX(GSM_CARRIER_BW, LMS_MIN_BW_SUPPORTED)
 #define SAMPLE_BUF_SZ    (1 << 20) /* Size of Rx timestamp based Ring buffer, in bytes */
 
+
+/* Device Name Prefixes as presented by LimeSuite API LMS_GetDeviceInfo(): */
+#define LMS_DEV_SDR_USB_PREFIX_NAME "LimeSDR-USB"
+#define LMS_DEV_SDR_MINI_PREFIX_NAME "LimeSDR-Mini"
+#define LMS_DEV_NET_MICRO_PREFIX_NAME "LimeNET-Micro"
+
+/* Device parameter descriptor */
+struct dev_desc {
+	/* Does LimeSuite allow switching the clock source for this device?
+	 * LimeSDR-Mini does not have switches but needs soldering to select
+	 * external/internal clock. Any call to LMS_SetClockFreq() will fail.
+	 */
+	bool clock_src_switchable;
+	/* Does LimeSuite allow using REF_INTERNAL for this device?
+	 * LimeNET-Micro does not like selecting internal clock
+	 */
+	bool clock_src_int_usable;
+	/* Device specific maximum tx levels selected by phasenoise measurements, in dB */
+	double max_tx_gain;
+	/* Device Name Prefix as presented by LimeSuite API LMS_GetDeviceInfo() */
+	std::string name_prefix;
+};
+
+static const std::map<enum lms_dev_type, struct dev_desc> dev_param_map {
+	{ LMS_DEV_SDR_USB,   { true,  true,  73.0, LMS_DEV_SDR_USB_PREFIX_NAME } },
+	{ LMS_DEV_SDR_MINI,  { false, true,  66.0, LMS_DEV_SDR_MINI_PREFIX_NAME } },
+	{ LMS_DEV_NET_MICRO, { true,  false, 71.0, LMS_DEV_NET_MICRO_PREFIX_NAME } },
+	{ LMS_DEV_UNKNOWN,   { true,  true,  73.0, "UNKNOWN" } },
+};
+
+static enum lms_dev_type parse_dev_type(lms_device_t *m_lms_dev)
+{
+	std::map<enum lms_dev_type, struct dev_desc>::const_iterator it = dev_param_map.begin();
+
+	const lms_dev_info_t* device_info = LMS_GetDeviceInfo(m_lms_dev);
+
+	while (it != dev_param_map.end())
+	{
+		enum lms_dev_type dev_type = it->first;
+		struct dev_desc desc = it->second;
+
+		if (strncmp(device_info->deviceName, desc.name_prefix.c_str(), desc.name_prefix.length()) == 0) {
+			LOGC(DDEV, INFO) << "Device identified as " << desc.name_prefix;
+			return dev_type;
+		}
+		it++;
+	}
+	return LMS_DEV_UNKNOWN;
+}
+
 LMSDevice::LMSDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chan_num, double lo_offset,
 		     const std::vector<std::string>& tx_paths,
 		     const std::vector<std::string>& rx_paths):
 	RadioDevice(tx_sps, rx_sps, iface, chan_num, lo_offset, tx_paths, rx_paths),
-	m_lms_dev(NULL), started(false)
+	m_lms_dev(NULL), started(false), m_dev_type(LMS_DEV_UNKNOWN)
 {
 	LOGC(DDEV, INFO) << "creating LMS device...";
 
@@ -138,11 +192,11 @@
 int LMSDevice::open(const std::string &args, int ref, bool swap_channels)
 {
 	lms_info_str_t* info_list;
-	const lms_dev_info_t* device_info;
 	lms_range_t range_sr;
 	float_type sr_host, sr_rf;
 	unsigned int i, n;
 	int rc, dev_id;
+	struct dev_desc dev_desc;
 
 	LOGC(DDEV, INFO) << "Opening LMS device..";
 
@@ -179,19 +233,20 @@
 
 	delete [] info_list;
 
-	device_info = LMS_GetDeviceInfo(m_lms_dev);
+	m_dev_type = parse_dev_type(m_lms_dev);
+	dev_desc = dev_param_map.at(m_dev_type);
 
 	if ((ref != REF_EXTERNAL) && (ref != REF_INTERNAL)){
 		LOGC(DDEV, ERROR) << "Invalid reference type";
 		goto out_close;
 	}
 
-	/* if reference clock is external setup must happen _before_ calling LMS_Init */
-	/* FIXME make external reference frequency configurable */
+	/* if reference clock is external, setup must happen _before_ calling LMS_Init */
 	if (ref == REF_EXTERNAL) {
 		LOGC(DDEV, INFO) << "Setting External clock reference to 10MHz";
-		/* Assume an external 10 MHz reference clock */
-		if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, 10000000.0) < 0)
+		/* FIXME: Assume an external 10 MHz reference clock. make
+		   external reference frequency configurable */
+		if (!do_clock_src_freq(REF_EXTERNAL, 10000000.0))
 			goto out_close;
 	}
 
@@ -201,22 +256,13 @@
 		goto out_close;
 	}
 
-	/* LimeSDR-Mini does not have switches but needs soldering to select external/internal clock */
-	/* LimeNET-Micro also does not like selecting internal clock*/
-	/* also set device specific maximum tx levels selected by phasenoise measurements*/
-	if (strncmp(device_info->deviceName,"LimeSDR-USB",11) == 0){
-		/* if reference clock is internal setup must happen _after_ calling LMS_Init */
-		/* according to lms using LMS_CLOCK_EXTREF with a frequency <= 0 is the correct way to set clock to internal reference*/
-		if (ref == REF_INTERNAL) {
-			LOGC(DDEV, INFO) << "Setting Internal clock reference";
-			if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, -1) < 0)
-				goto out_close;
-		}
-		maxTxGainClamp = 73.0;
-	} else if (strncmp(device_info->deviceName,"LimeSDR-Mini",12) == 0)
-		maxTxGainClamp = 66.0;
-	else
-		maxTxGainClamp = 71.0; /* "LimeNET-Micro", etc FIXME pciE based LMS boards?*/
+	/* if reference clock is internal, setup must happen _after_ calling LMS_Init */
+	if (ref == REF_INTERNAL) {
+		LOGC(DDEV, INFO) << "Setting Internal clock reference";
+		/* Internal freq param is not used */
+		if (!do_clock_src_freq(REF_INTERNAL, 0))
+			goto out_close;
+	}
 
 	/* enable all used channels */
 	for (i=0; i<chans; i++) {
@@ -342,6 +388,43 @@
 	return true;
 }
 
+bool LMSDevice::do_clock_src_freq(enum ReferenceType ref, double freq)
+{
+	struct dev_desc dev_desc = dev_param_map.at(m_dev_type);
+	size_t lms_clk_id;
+
+	switch (ref) {
+	case REF_EXTERNAL:
+		lms_clk_id = LMS_CLOCK_EXTREF;
+		break;
+	case REF_INTERNAL:
+		if (!dev_desc.clock_src_int_usable) {
+			LOGC(DDEV, ERROR) << "Device type " << dev_desc.name_prefix
+					  << " doesn't support internal reference clock";
+			return false;
+		}
+		/* According to lms using LMS_CLOCK_EXTREF with a
+		   frequency <= 0 is the correct way to set clock to
+		   internal reference */
+		lms_clk_id = LMS_CLOCK_EXTREF;
+		freq = -1;
+		break;
+	default:
+		LOGC(DDEV, ERROR) << "Invalid reference type " << get_value_string(clock_ref_names, ref);
+		return false;
+	}
+
+	if (dev_desc.clock_src_switchable) {
+		if (LMS_SetClockFreq(m_lms_dev, lms_clk_id, freq) < 0)
+			return false;
+	} else {
+		LOGC(DDEV, INFO) << "Device type " << dev_desc.name_prefix
+				 << " doesn't support switching clock source through SW";
+	}
+
+	return true;
+}
+
 /* do rx/tx calibration - depends on gain, freq and bw */
 bool LMSDevice::do_calib(size_t chan)
 {
@@ -383,7 +466,7 @@
 
 double LMSDevice::maxTxGain()
 {
-	return maxTxGainClamp;
+	return dev_param_map.at(m_dev_type).max_tx_gain;
 }
 
 double LMSDevice::minTxGain()
diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h
index cdba72c..755f6c4 100644
--- a/Transceiver52M/device/lms/LMSDevice.h
+++ b/Transceiver52M/device/lms/LMSDevice.h
@@ -41,6 +41,13 @@
  * 	A^2 = 1 */
 #define LIMESDR_TX_AMPL  0.707
 
+enum lms_dev_type {
+	LMS_DEV_SDR_USB,   /* LimeSDR-USB */
+	LMS_DEV_SDR_MINI,  /* LimeSDR-Mini */
+	LMS_DEV_NET_MICRO, /* LimeNet-micro */
+	LMS_DEV_UNKNOWN,
+};
+
 /** A class to handle a LimeSuite supported device */
 class LMSDevice:public RadioDevice {
 
@@ -59,7 +66,8 @@
 	TIMESTAMP ts_initial, ts_offset;
 
 	std::vector<double> tx_gains, rx_gains;
-	double maxTxGainClamp;
+
+	enum lms_dev_type m_dev_type;
 
 	bool do_calib(size_t chan);
 	bool do_filters(size_t chan);
@@ -68,6 +76,7 @@
 	bool flush_recv(size_t num_pkts);
 	void update_stream_stats_rx(size_t chan, bool *overrun);
 	void update_stream_stats_tx(size_t chan, bool *underrun);
+	bool do_clock_src_freq(enum ReferenceType ref, double freq);
 
 public:
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-trx/+/16876
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Change-Id: I7658615787c5bc41c365bab9c11733b701ac2ae5
Gerrit-Change-Number: 16876
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200116/3b246d0f/attachment.htm>


More information about the gerrit-log mailing list