Transceiver52M: Add option to explicitly set GPSDO reference

Before UHD version 3.9.0 on-board GPSDO modules for USRP
devices were automatically enabled if detected. After UHD
version 3.9.0 the UHD behavior changed to require explicit
setting of the reference to enable GPSDO use.

Modify the interfaces to pass 'internal', 'external' and
'gpsdo' reference options from configuration database into
the UHD driver layer. Convert the 'TRX.reference' entry in
the configuration from a boolean value to string.
This commit is contained in:
Tom Tsou
2016-08-30 19:35:32 -07:00
committed by Michael Iedema
parent 2992951933
commit c438a5a689
6 changed files with 54 additions and 20 deletions

View File

@@ -211,7 +211,7 @@ public:
uhd_device(int sps, bool skip_rx);
~uhd_device();
int open(const std::string &args, bool extref);
int open(const std::string &args, ReferenceType ref);
bool start();
bool stop();
void restart(uhd::time_spec_t ts);
@@ -290,7 +290,7 @@ private:
smpl_buf *rx_smpl_buf;
void init_gains();
void set_ref_clk(bool ext_clk);
void set_ref_clk(ReferenceType ref);
int set_master_clk(double rate);
int set_rates(double tx_rate, double rx_rate);
bool parse_dev_type();
@@ -375,12 +375,26 @@ void uhd_device::init_gains()
return;
}
void uhd_device::set_ref_clk(bool ext_clk)
void uhd_device::set_ref_clk(ReferenceType ref)
{
if (ext_clk)
usrp_dev->set_clock_source("external");
const char *refstr;
return;
switch (ref) {
case REF_INTERNAL:
refstr = "internal";
break;
case REF_EXTERNAL:
refstr = "external";
break;
case REF_GPS:
refstr = "gpsdo";
break;
default:
LOG(ALERT) << "Invalid reference type";
return;
}
usrp_dev->set_clock_source(refstr);
}
int uhd_device::set_master_clk(double clk_rate)
@@ -525,7 +539,7 @@ bool uhd_device::parse_dev_type()
return true;
}
int uhd_device::open(const std::string &args, bool extref)
int uhd_device::open(const std::string &args, ReferenceType ref)
{
// Find UHD devices
uhd::device_addr_t addr(args);
@@ -548,8 +562,7 @@ int uhd_device::open(const std::string &args, bool extref)
if (!parse_dev_type())
return -1;
if (extref)
set_ref_clk(true);
set_ref_clk(ref);
// Create TX and RX streamers
uhd::stream_args_t stream_args("sc16");

View File

@@ -90,7 +90,7 @@ USRPDevice::USRPDevice(int sps, bool skipRx)
#endif
}
int USRPDevice::open(const std::string &, bool)
int USRPDevice::open(const std::string &, ReferenceType)
{
writeLock.unlock();

View File

@@ -105,7 +105,7 @@ private:
USRPDevice(int sps, bool skipRx);
/** Instantiate the USRP */
int open(const std::string &, bool);
int open(const std::string &, ReferenceType);
/** Start the USRP */
bool start();

View File

@@ -36,10 +36,14 @@ class RadioDevice {
/* Radio interface types */
enum RadioInterfaceType { NORMAL, RESAMP_64M, RESAMP_100M };
enum ReferenceType { REF_INTERNAL, REF_EXTERNAL, REF_GPS };
static RadioDevice *make(int sps, bool skipRx = false);
virtual ~RadioDevice() { }
/** Initialize the USRP */
virtual int open(const std::string &args = "", bool extref = false)=0;
virtual int open(const std::string &args, ReferenceType ref)=0;
/** Start the USRP */
virtual bool start()=0;

View File

@@ -111,9 +111,10 @@ int testConfig(const char *filename)
int main(int argc, char *argv[])
{
int trxPort, radioType, extref = 0, fail = 0;
std::string deviceArgs, logLevel, trxAddr;
int trxPort, radioType, fail = 0;
std::string deviceArgs, logLevel, trxAddr, refstr;
RadioDevice *usrp = NULL;
RadioDevice::ReferenceType refType;
RadioInterface *radio = NULL;
Transceiver *trx = NULL;
@@ -143,19 +144,34 @@ int main(int argc, char *argv[])
trxAddr = gConfig.getStr("TRX.IP");
if (gConfig.defines("TRX.Reference"))
extref = gConfig.getNum("TRX.Reference");
refstr = gConfig.getStr("TRX.Reference");
if (extref)
std::cout << "Using external clock reference" << std::endl;
else
std::cout << "Using internal clock reference" << std::endl;
/*
* We could get complicated here on search strings, but just use common
* cases for ease of use.
*/
if ((refstr.find("GPS") != std::string::npos) ||
(refstr.find("gps") != std::string::npos)) {
refType = RadioDevice::REF_GPS;
refstr = "gpsdo";
} else if ((refstr.find("External") != std::string::npos) ||
(refstr.find("EXTERNAL") != std::string::npos) ||
(refstr.find("external") != std::string::npos)) {
refType = RadioDevice::REF_EXTERNAL;
refstr = "external";
} else {
refType = RadioDevice::REF_INTERNAL;
refstr = "internal";
}
std::cout << "Using " << refstr << " frequency reference" << std::endl;
gLogInit("transceiver", logLevel.c_str(), LOG_LOCAL7);
srandom(time(NULL));
usrp = RadioDevice::make(SPS);
radioType = usrp->open(deviceArgs, extref);
radioType = usrp->open(deviceArgs, refType);
if (radioType < 0) {
LOG(ALERT) << "Transceiver exiting..." << std::endl;
return EXIT_FAILURE;

View File

@@ -237,6 +237,7 @@ INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.RadioFrequencyOffset','128',1,0,'Fine
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.Timeout.Clock','10',0,0,'How long to wait during a read operation from the Transceiver before giving up.');
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.Timeout.Start','2',0,0,'How long to wait during system startup before checking to see if the Transceiver can be reached.');
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.TxAttenOffset','0',1,0,'Hardware-specific gain adjustment for transmitter, matched to the power amplifier, expessed as an attenuation in dB. Set at the factory. Do not adjust without proper calibration. Static.');
INSERT OR IGNORE INTO "CONFIG" VALUES('TRX.Reference','internal',0,0,'TRX reference type ("internal", "external", "gpsdo")');
INSERT OR IGNORE INTO "CONFIG" VALUES('Test.GSM.SimulatedFER.Downlink','0',0,0,'Probability (0-100) of dropping any downlink frame to test robustness.');
INSERT OR IGNORE INTO "CONFIG" VALUES('Test.GSM.SimulatedFER.Uplink','0',0,0,'Probability (0-100) of dropping any uplink frame to test robustness.');
INSERT OR IGNORE INTO "CONFIG" VALUES('Test.GSM.UplinkFuzzingRate','0',1,0,'Probability (0-100) of flipping a bit in any uplink frame to test robustness. Static.');