From c438a5a689b32539d1c4ce8dd607d0231451faa9 Mon Sep 17 00:00:00 2001 From: Tom Tsou Date: Tue, 30 Aug 2016 19:35:32 -0700 Subject: [PATCH] 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. --- Transceiver52M/UHDDevice.cpp | 31 +++++++++++++++++++++--------- Transceiver52M/USRPDevice.cpp | 2 +- Transceiver52M/USRPDevice.h | 2 +- Transceiver52M/radioDevice.h | 6 +++++- Transceiver52M/runTransceiver.cpp | 32 +++++++++++++++++++++++-------- apps/OpenBTS.example.sql | 1 + 6 files changed, 54 insertions(+), 20 deletions(-) diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp index 1c4f1ab..d52be55 100644 --- a/Transceiver52M/UHDDevice.cpp +++ b/Transceiver52M/UHDDevice.cpp @@ -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"); diff --git a/Transceiver52M/USRPDevice.cpp b/Transceiver52M/USRPDevice.cpp index 1fff124..190b11b 100644 --- a/Transceiver52M/USRPDevice.cpp +++ b/Transceiver52M/USRPDevice.cpp @@ -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(); diff --git a/Transceiver52M/USRPDevice.h b/Transceiver52M/USRPDevice.h index 9a2d3d9..6c57519 100644 --- a/Transceiver52M/USRPDevice.h +++ b/Transceiver52M/USRPDevice.h @@ -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(); diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h index 7c2f951..4017439 100644 --- a/Transceiver52M/radioDevice.h +++ b/Transceiver52M/radioDevice.h @@ -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; diff --git a/Transceiver52M/runTransceiver.cpp b/Transceiver52M/runTransceiver.cpp index dfac8d4..c06d3c3 100644 --- a/Transceiver52M/runTransceiver.cpp +++ b/Transceiver52M/runTransceiver.cpp @@ -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; diff --git a/apps/OpenBTS.example.sql b/apps/OpenBTS.example.sql index 916ff14..1610138 100644 --- a/apps/OpenBTS.example.sql +++ b/apps/OpenBTS.example.sql @@ -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.');