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.');