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/.
Pau Espin Pedrol gerrit-no-reply at lists.osmocom.org
Review at https://gerrit.osmocom.org/6238
Add support to set Rx/TxAntenna
Change-Id: I1735e6ab05a05b0312d6d679b16ebd4a2260fa23
---
M Transceiver52M/UHDDevice.cpp
M Transceiver52M/USRPDevice.cpp
M Transceiver52M/USRPDevice.h
M Transceiver52M/osmo-trx.cpp
M Transceiver52M/radioDevice.h
5 files changed, 273 insertions(+), 57 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/38/6238/1
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index 09317a9..1cf6cb9 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -1,5 +1,5 @@
/*
- * Device support for Ettus Research UHD driver
+ * Device support for Ettus Research UHD driver
*
* Copyright 2010,2011 Free Software Foundation, Inc.
* Copyright (C) 2015 Ettus Research LLC
@@ -143,8 +143,8 @@
public:
/** Sample buffer constructor
@param len number of 32-bit samples the buffer should hold
- @param rate sample clockrate
- @param timestamp
+ @param rate sample clockrate
+ @param timestamp
*/
smpl_buf(size_t len, double rate);
~smpl_buf();
@@ -172,7 +172,7 @@
*/
std::string str_status(size_t ts) const;
- /** Formatted error string
+ /** Formatted error string
@param code an error code
@return a formatted error string
*/
@@ -208,7 +208,9 @@
class uhd_device : public RadioDevice {
public:
uhd_device(size_t tx_sps, size_t rx_sps, InterfaceType type,
- size_t chans, double offset);
+ size_t chans, double offset,
+ const std::vector<std::string>& tx_paths,
+ const std::vector<std::string>& rx_paths);
~uhd_device();
int open(const std::string &args, int ref, bool swap_channels);
@@ -248,6 +250,11 @@
double getRxFreq(size_t chan);
double getRxFreq();
+ bool setRxAntenna(const std::string &ant, size_t chan);
+ std::string getRxAntenna(size_t chan);
+ bool setTxAntenna(const std::string &ant, size_t chan);
+ std::string getTxAntenna(size_t chan);
+
inline double getSampleRate() { return tx_rate; }
inline double numberRead() { return rx_pkt_cnt; }
inline double numberWritten() { return 0; }
@@ -280,6 +287,7 @@
std::vector<double> tx_gains, rx_gains;
std::vector<double> tx_freqs, rx_freqs;
+ std::vector<std::string> tx_paths, rx_paths;
size_t tx_spp, rx_spp;
bool started;
@@ -295,6 +303,7 @@
void init_gains();
void set_channels(bool swap);
void set_rates();
+ bool set_antennas();
bool parse_dev_type();
bool flush_recv(size_t num_pkts);
int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);
@@ -353,7 +362,9 @@
}
uhd_device::uhd_device(size_t tx_sps, size_t rx_sps,
- InterfaceType iface, size_t chans, double offset)
+ InterfaceType iface, size_t chans, double offset,
+ const std::vector<std::string>& tx_paths,
+ const std::vector<std::string>& rx_paths)
: tx_gain_min(0.0), tx_gain_max(0.0),
rx_gain_min(0.0), rx_gain_max(0.0),
tx_spp(0), rx_spp(0),
@@ -365,6 +376,8 @@
this->chans = chans;
this->offset = offset;
this->iface = iface;
+ this->tx_paths = tx_paths;
+ this->rx_paths = rx_paths;
}
uhd_device::~uhd_device()
@@ -439,6 +452,33 @@
ts_offset = static_cast<TIMESTAMP>(desc.offset * rx_rate);
LOG(INFO) << "Rates configured for " << desc.str;
+}
+
+bool uhd_device::set_antennas()
+{
+ unsigned int i;
+
+ for (i = 0; i < tx_paths.size(); i++) {
+ if (tx_paths[i] == "")
+ continue;
+ LOG(DEBUG) << "Configuring channel " << i << " with antenna " << tx_paths[i];
+ if (!setTxAntenna(tx_paths[i], i)) {
+ LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << tx_paths[i];
+ return false;
+ }
+ }
+
+ for (i = 0; i < rx_paths.size(); i++) {
+ if (rx_paths[i] == "")
+ continue;
+ LOG(DEBUG) << "Configuring channel " << i << " with antenna " << tx_paths[i];
+ if (!setRxAntenna(rx_paths[i], i)) {
+ LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << rx_paths[i];
+ return false;
+ }
+ }
+ LOG(INFO) << "Antennas configured successfully";
+ return true;
}
double uhd_device::setTxGain(double db, size_t chan)
@@ -644,6 +684,11 @@
return -1;
}
+ if (!set_antennas()) {
+ LOG(ALERT) << "UHD antenna setting failed";
+ return -1;
+ }
+
tx_freqs.resize(chans);
rx_freqs.resize(chans);
tx_gains.resize(chans);
@@ -705,7 +750,7 @@
for (size_t i = 0; i < rx_buffers.size(); i++)
rx_buffers[i] = new smpl_buf(buf_len, rx_rate);
- // Initialize and shadow gain values
+ // Initialize and shadow gain values
init_gains();
// Print configuration
@@ -926,7 +971,7 @@
rx_pkt_cnt++;
- // Check for errors
+ // Check for errors
rc = check_rx_md_err(metadata, num_smpls);
switch (rc) {
case ERROR_UNRECOVERABLE:
@@ -1163,6 +1208,72 @@
}
return rx_freqs[chan];
+}
+
+bool uhd_device::setRxAntenna(const std::string &ant, size_t chan)
+{
+ std::vector<std::string> avail;
+ if (chan >= rx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return false;
+ }
+
+ avail = usrp_dev->get_rx_antennas(chan);
+ if (std::find(avail.begin(), avail.end(), ant) == avail.end()) {
+ LOG(ALERT) << "Requested non-existent antenna " << ant << " on channel " << chan;
+ return false;
+ }
+ usrp_dev->set_rx_antenna(ant, chan);
+ rx_paths[chan] = usrp_dev->get_rx_antenna(chan);
+
+ if (ant != rx_paths[chan]) {
+ LOG(ALERT) << "Failed setting antenna " << ant << " on channel " << chan << ", got instead " << rx_paths[chan];
+ return false;
+ }
+
+ return true;
+}
+
+std::string uhd_device::getRxAntenna(size_t chan)
+{
+ if (chan >= rx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return "";
+ }
+ return usrp_dev->get_rx_antenna(chan);
+}
+
+bool uhd_device::setTxAntenna(const std::string &ant, size_t chan)
+{
+ std::vector<std::string> avail;
+ if (chan >= tx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return false;
+ }
+
+ avail = usrp_dev->get_tx_antennas(chan);
+ if (std::find(avail.begin(), avail.end(), ant) == avail.end()) {
+ LOG(ALERT) << "Requested non-existent antenna " << ant << " on channel " << chan;
+ return false;
+ }
+ usrp_dev->set_tx_antenna(ant, chan);
+ tx_paths[chan] = usrp_dev->get_tx_antenna(chan);
+
+ if (ant != tx_paths[chan]) {
+ LOG(ALERT) << "Failed setting antenna " << ant << " on channel " << chan << ", got instead " << tx_paths[chan];
+ return false;
+ }
+
+ return true;
+}
+
+std::string uhd_device::getTxAntenna(size_t chan)
+{
+ if (chan >= tx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return "";
+ }
+ return usrp_dev->get_tx_antenna(chan);
}
/*
@@ -1451,7 +1562,9 @@
}
RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps,
- InterfaceType iface, size_t chans, double offset)
+ InterfaceType iface, size_t chans, double offset,
+ const std::vector<std::string>& tx_paths,
+ const std::vector<std::string>& rx_paths)
{
- return new uhd_device(tx_sps, rx_sps, iface, chans, offset);
+ return new uhd_device(tx_sps, rx_sps, iface, chans, offset, tx_paths, rx_paths);
}
diff --git a/Transceiver52M/USRPDevice.cpp b/Transceiver52M/USRPDevice.cpp
index e5be58d..f7f24e9 100644
--- a/Transceiver52M/USRPDevice.cpp
+++ b/Transceiver52M/USRPDevice.cpp
@@ -27,7 +27,7 @@
Compilation Flags
SWLOOPBACK compile for software loopback testing
-*/
+*/
#include <stdint.h>
@@ -80,7 +80,7 @@
else
pingOffset = 0;
-#ifdef SWLOOPBACK
+#ifdef SWLOOPBACK
samplePeriod = 1.0e6/actualSampleRate;
loopbackBufferSize = 0;
gettimeofday(&lastReadTime,NULL);
@@ -93,9 +93,9 @@
writeLock.unlock();
LOG(INFO) << "opening USRP device..";
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
string rbf = "std_inband.rbf";
- //string rbf = "inband_1rxhb_1tx.rbf";
+ //string rbf = "inband_1rxhb_1tx.rbf";
m_uRx.reset();
if (!skipRx) {
try {
@@ -144,7 +144,7 @@
if (!skipRx) m_uRx->stop();
m_uTx->stop();
-
+
#endif
switch (dboardConfig) {
@@ -175,19 +175,19 @@
samplesRead = 0;
samplesWritten = 0;
started = false;
-
+
return NORMAL;
}
-bool USRPDevice::start()
+bool USRPDevice::start()
{
LOG(INFO) << "starting USRP...";
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
if (!m_uRx && !skipRx) return false;
if (!m_uTx) return false;
-
+
if (!skipRx) m_uRx->stop();
m_uTx->stop();
@@ -217,8 +217,8 @@
hi32Timestamp = 0;
isAligned = false;
-
- if (!skipRx)
+
+ if (!skipRx)
started = (m_uRx->start() && m_uTx->start());
else
started = m_uTx->start();
@@ -229,14 +229,14 @@
#endif
}
-bool USRPDevice::stop()
+bool USRPDevice::stop()
{
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
if (!m_uRx) return false;
if (!m_uTx) return false;
-
+
delete[] currData;
-
+
started = !(m_uRx->stop() && m_uTx->stop());
return !started;
#else
@@ -257,7 +257,7 @@
double USRPDevice::maxRxGain()
{
return m_dbRx->gain_max();
-}
+}
double USRPDevice::minRxGain()
{
@@ -313,28 +313,68 @@
return dB;
}
+bool USRPDevice::setRxAntenna(const std::string &ant, size_t chan)
+{
+ if (chan >= rx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return false;
+ }
+ LOG(ALERT) << "Not implemented";
+ return true;
+}
+
+std::string USRPDevice::getRxAntenna(size_t chan)
+{
+ if (chan >= rx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return "";
+ }
+ LOG(ALERT) << "Not implemented";
+ return "";
+}
+
+bool USRPDevice::setTxAntenna(const std::string &ant, size_t chan)
+{
+ if (chan >= tx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return false;
+ }
+ LOG(ALERT) << "Not implemented";
+ return true;
+}
+
+std::string USRPDevice::getTxAntenna(size_t chan)
+{
+ if (chan >= tx_paths.size()) {
+ LOG(ALERT) << "Requested non-existent channel " << chan;
+ return "";
+ }
+ LOG(ALERT) << "Not implemented";
+ return "";
+}
+
// NOTE: Assumes sequential reads
int USRPDevice::readSamples(std::vector<short *> &bufs, int len, bool *overrun,
TIMESTAMP timestamp, bool *underrun, unsigned *RSSI)
{
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
if (!m_uRx)
return 0;
short *buf = bufs[0];
timestamp += timestampOffset;
-
+
if (timestamp + len < timeStart) {
memset(buf,0,len*2*sizeof(short));
return len;
}
if (underrun) *underrun = false;
-
+
uint32_t readBuf[2000];
-
+
while (1) {
//guestimate USB read size
int readLen=0;
@@ -344,7 +384,7 @@
readLen = 512 * ((int) ceil((float) numSamplesNeeded/126.0));
if (readLen > 8000) readLen= (8000/512)*512;
}
-
+
// read USRP packets, parse and save A/D data as needed
readLen = m_uRx->read((void *)readBuf,readLen,overrun);
for(int pktNum = 0; pktNum < (readLen/512); pktNum++) {
@@ -381,13 +421,13 @@
continue;
}
if ((word0 >> 28) & 0x04) {
- if (underrun) *underrun = true;
+ if (underrun) *underrun = true;
LOG(DEBUG) << "UNDERRUN in TRX->USRP interface";
}
if (RSSI) *RSSI = (word0 >> 21) & 0x3f;
-
+
if (!isAligned) continue;
-
+
unsigned cursorStart = pktTimestamp - timeStart + dataStart;
while (cursorStart*2 > currDataSize) {
cursorStart -= currDataSize/2;
@@ -400,17 +440,17 @@
else {
memcpy(data+cursorStart*2,tmpBuf+2,payloadSz);
}
- if (pktTimestamp + payloadSz/2/sizeof(short) > timeEnd)
+ if (pktTimestamp + payloadSz/2/sizeof(short) > timeEnd)
timeEnd = pktTimestamp+payloadSz/2/sizeof(short);
LOG(DEBUG) << "timeStart: " << timeStart << ", timeEnd: " << timeEnd << ", pktTimestamp: " << pktTimestamp;
- }
- }
-
+ }
+ }
+
// copy desired data to buf
unsigned bufStart = dataStart+(timestamp-timeStart);
- if (bufStart + len < currDataSize/2) {
+ if (bufStart + len < currDataSize/2) {
LOG(DEBUG) << "bufStart: " << bufStart;
memcpy(buf,data+bufStart*2,len*2*sizeof(short));
memset(data+bufStart*2,0,len*2*sizeof(short));
@@ -428,21 +468,21 @@
timeStart = timestamp + len;
return len;
-
+
#else
if (loopbackBufferSize < 2) return 0;
int numSamples = 0;
struct timeval currTime;
gettimeofday(&currTime,NULL);
- double timeElapsed = (currTime.tv_sec - lastReadTime.tv_sec)*1.0e6 +
+ double timeElapsed = (currTime.tv_sec - lastReadTime.tv_sec)*1.0e6 +
(currTime.tv_usec - lastReadTime.tv_usec);
if (timeElapsed < samplePeriod) {return 0;}
int numSamplesToRead = (int) floor(timeElapsed/samplePeriod);
if (numSamplesToRead < len) return 0;
-
+
if (numSamplesToRead > len) numSamplesToRead = len;
if (numSamplesToRead > loopbackBufferSize/2) {
- firstRead =false;
+ firstRead =false;
numSamplesToRead = loopbackBufferSize/2;
}
memcpy(buf,loopbackBuffer,sizeof(short)*2*numSamplesToRead);
@@ -460,7 +500,7 @@
firstRead = true;
}
samplesRead += numSamples;
-
+
return numSamples;
#endif
}
@@ -471,7 +511,7 @@
{
writeLock.lock();
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
if (!m_uTx)
return 0;
@@ -518,14 +558,14 @@
memcpy(loopbackBuffer+loopbackBufferSize,buf,sizeof(short)*2*len);
samplesWritten += retVal;
loopbackBufferSize += retVal*2;
-
+
return retVal;
#endif
}
-bool USRPDevice::updateAlignment(TIMESTAMP timestamp)
+bool USRPDevice::updateAlignment(TIMESTAMP timestamp)
{
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
short data[] = {0x00,0x02,0x00,0x00};
uint32_t *wordPtr = (uint32_t *) data;
*wordPtr = host_to_usrp_u32(*wordPtr);
@@ -542,7 +582,7 @@
#endif
}
-#ifndef SWLOOPBACK
+#ifndef SWLOOPBACK
bool USRPDevice::setTxFreq(double wFreq, size_t chan)
{
usrp_tune_result result;
@@ -600,7 +640,9 @@
#endif
RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps,
- RadioDevice::InterfaceType, size_t chans, double)
+ InterfaceType iface, size_t chans, double offset,
+ const std::vector<std::string>& tx_paths,
+ const std::vector<std::string>& rx_paths)
{
return new USRPDevice(tx_sps);
}
diff --git a/Transceiver52M/USRPDevice.h b/Transceiver52M/USRPDevice.h
index b560339..f5fbe85 100644
--- a/Transceiver52M/USRPDevice.h
+++ b/Transceiver52M/USRPDevice.h
@@ -83,10 +83,10 @@
double rxGain;
-#ifdef SWLOOPBACK
+#ifdef SWLOOPBACK
short loopbackBuffer[1000000];
int loopbackBufferSize;
- double samplePeriod;
+ double samplePeriod;
struct timeval startTime;
struct timeval lastReadTime;
@@ -179,6 +179,18 @@
/** return minimum Rx Gain **/
double minTxGain(void);
+ /** sets the RX path to use, returns true if successful and false otherwise */
+ bool setRxAntenna(const std::string &ant, size_t chan = 0);
+
+ /* return the used RX path */
+ std::string getRxAntenna(size_t chan = 0);
+
+ /** sets the RX path to use, returns true if successful and false otherwise */
+ bool setTxAntenna(const std::string &ant, size_t chan = 0);
+
+ /* return the used RX path */
+ std::string getTxAntenna(size_t chan = 0);
+
/** Return internal status values */
inline double getTxFreq(size_t chan = 0) { return 0; }
inline double getRxFreq(size_t chan = 0) { return 0; }
@@ -189,4 +201,3 @@
};
#endif // _USRP_DEVICE_H_
-
diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp
index 44da638..f1e41ee 100644
--- a/Transceiver52M/osmo-trx.cpp
+++ b/Transceiver52M/osmo-trx.cpp
@@ -28,6 +28,10 @@
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
+#include <vector>
+#include <string>
+#include <sstream>
+#include <iostream>
#include <GSMCommon.h>
#include <Logger.h>
@@ -79,6 +83,8 @@
bool swap_channels;
bool edge;
int sched_rr;
+ std::vector<std::string> rx_paths;
+ std::vector<std::string> tx_paths;
};
volatile bool gshutdown = false;
@@ -241,6 +247,21 @@
}
}
+
+static std::vector<std::string> comma_delimited_to_vector(char* opt) {
+ std::string str = std::string(opt);
+ std::vector<std::string> result;
+ std::stringstream ss(str);
+
+ while( ss.good() )
+ {
+ std::string substr;
+ getline(ss, substr, ',');
+ result.push_back(substr);
+ }
+ return result;
+}
+
static void print_help()
{
fprintf(stdout, "Options:\n"
@@ -263,7 +284,9 @@
" -A Random Access Burst test mode with delay\n"
" -R RSSI to dBm offset in dB (default=0)\n"
" -S Swap channels (UmTRX only)\n"
- " -t SCHED_RR real-time priority (1..32)\n",
+ " -t SCHED_RR real-time priority (1..32)\n"
+ " -y comma-delimited list of Tx paths (num elements matches -c)\n"
+ " -z comma-delimited list of Rx paths (num elements matches -c)\n",
"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
}
@@ -289,8 +312,10 @@
config->swap_channels = false;
config->edge = false;
config->sched_rr = -1;
+ config->tx_paths = std::vector<std::string>(DEFAULT_CHANS, "");
+ config->rx_paths = std::vector<std::string>(DEFAULT_CHANS, "");
- while ((option = getopt(argc, argv, "ha:l:i:j:p:c:dmxgfo:s:b:r:A:R:Set:")) != -1) {
+ while ((option = getopt(argc, argv, "ha:l:i:j:p:c:dmxgfo:s:b:r:A:R:Set:y:z:")) != -1) {
switch (option) {
case 'h':
print_help();
@@ -355,6 +380,11 @@
case 't':
config->sched_rr = atoi(optarg);
break;
+ case 'y':
+ config->tx_paths = comma_delimited_to_vector(optarg);
+ case 'z':
+ config->rx_paths = comma_delimited_to_vector(optarg);
+ break;
default:
print_help();
exit(0);
@@ -390,6 +420,12 @@
printf("RACH delay is too big %i\n\n", config->rach_delay);
goto bad_config;
}
+
+ if(config->tx_paths.size() != config->chans ||
+ config->rx_paths.size() != config->chans) {
+ printf("Num of channels and num of tx/rx_paths doesn't match\n\n");
+ goto bad_config;
+ }
return;
@@ -480,7 +516,7 @@
ref = RadioDevice::REF_INTERNAL;
usrp = RadioDevice::make(config.tx_sps, config.rx_sps, iface,
- config.chans, config.offset);
+ config.chans, config.offset, config.tx_paths, config.rx_paths);
type = usrp->open(config.dev_args, ref, config.swap_channels);
if (type < 0) {
LOG(ALERT) << "Failed to create radio device" << std::endl;
diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h
index 3624c58..8045cf6 100644
--- a/Transceiver52M/radioDevice.h
+++ b/Transceiver52M/radioDevice.h
@@ -50,7 +50,9 @@
};
static RadioDevice *make(size_t tx_sps, size_t rx_sps, InterfaceType type,
- size_t chans = 1, double offset = 0.0);
+ size_t chans = 1, double offset = 0.0,
+ const std::vector<std::string>& tx_paths = std::vector<std::string>(1, ""),
+ const std::vector<std::string>& rx_paths = std::vector<std::string>(1, ""));
/** Initialize the USRP */
virtual int open(const std::string &args, int ref, bool swap_channels)=0;
@@ -136,6 +138,18 @@
/** return minimum Tx Gain **/
virtual double minTxGain(void) = 0;
+ /** sets the RX path to use, returns true if successful and false otherwise */
+ virtual bool setRxAntenna(const std::string &ant, size_t chan = 0) = 0;
+
+ /* return the used RX path */
+ virtual std::string getRxAntenna(size_t chan = 0) = 0;
+
+ /** sets the RX path to use, returns true if successful and false otherwise */
+ virtual bool setTxAntenna(const std::string &ant, size_t chan = 0) = 0;
+
+ /* return the used RX path */
+ virtual std::string getTxAntenna(size_t chan = 0) = 0;
+
/** Return internal status values */
virtual double getTxFreq(size_t chan = 0) = 0;
virtual double getRxFreq(size_t chan = 0) = 0;
--
To view, visit https://gerrit.osmocom.org/6238
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1735e6ab05a05b0312d6d679b16ebd4a2260fa23
Gerrit-PatchSet: 1
Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>